open-coleslaw 0.2.0 → 0.2.2

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/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/server.ts","../src/tools/start-meeting.ts","../src/orchestrator/orchestrator.ts","../src/storage/agent-store.ts","../src/storage/meeting-store.ts","../src/storage/worker-store.ts","../src/storage/mention-store.ts","../src/storage/minutes-store.ts","../src/storage/task-store.ts","../src/types/agent.ts","../src/types/meeting.ts","../src/agents/departments.ts","../src/orchestrator/event-bus.ts","../src/utils/logger.ts","../src/orchestrator/leader-pool.ts","../src/agents/leader-prompts.ts","../src/agents/tiers.ts","../src/agents/worker-prompts.ts","../src/agents/agent-factory.ts","../src/agents/claude-invoker.ts","../src/orchestrator/meeting-runner.ts","../src/agents/project-analyzer.ts","../src/tools/get-meeting-status.ts","../src/tools/get-minutes.ts","../src/tools/compact-minutes.ts","../src/meeting/compactor.ts","../src/tools/execute-tasks.ts","../src/orchestrator/worker-manager.ts","../src/tools/get-agent-tree.ts","../src/tools/respond-to-mention.ts","../src/tools/get-mentions.ts","../src/tools/cancel-meeting.ts","../src/tools/list-meetings.ts","../src/tools/get-task-report.ts","../src/tools/create-capability.ts","../src/extension/capability-registry.ts","../src/utils/config.ts","../src/extension/generator.ts","../src/extension/guide-updater.ts","../src/extension/extension-manager.ts","../src/tools/get-cost-summary.ts","../src/utils/cost-tracker.ts","../src/tools/chain-meeting.ts","../src/dashboard/server.ts","../src/dashboard/html.ts","../src/dashboard/state-bridge.ts","../src/dashboard/client.ts"],"sourcesContent":["import { randomUUID } from 'node:crypto';\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';\nimport { createServer } from './server.js';\nimport { ensureDataDirs } from './utils/config.js';\nimport { startDashboard } from './dashboard/server.js';\n\nasync function main() {\n ensureDataDirs();\n\n // Start dashboard BEFORE MCP server (connect may block on stdio)\n const sessionId = randomUUID();\n const projectPath = process.cwd();\n const projectName = projectPath.split('/').pop() ?? 'unknown';\n\n startDashboard({ sessionId, projectPath, projectName }).catch(() => {});\n\n const server = createServer();\n const transport = new StdioServerTransport();\n await server.connect(transport);\n}\n\nmain().catch((error) => {\n console.error('Fatal error:', error);\n process.exit(1);\n});\n","import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport {\n startMeetingSchema,\n startMeetingHandler,\n getMeetingStatusSchema,\n getMeetingStatusHandler,\n getMinutesSchema,\n getMinutesHandler,\n compactMinutesSchema,\n compactMinutesHandler,\n executeTasksSchema,\n executeTasksHandler,\n getAgentTreeHandler,\n respondToMentionSchema,\n respondToMentionHandler,\n getMentionsSchema,\n getMentionsHandler,\n cancelMeetingSchema,\n cancelMeetingHandler,\n listMeetingsSchema,\n listMeetingsHandler,\n getTaskReportSchema,\n getTaskReportHandler,\n createCapabilitySchema,\n createCapabilityHandler,\n getCostSummarySchema,\n getCostSummaryHandler,\n chainMeetingSchema,\n chainMeetingHandler,\n} from './tools/index.js';\n\nexport function createServer(): McpServer {\n const server = new McpServer({\n name: 'open-coleslaw',\n version: '0.1.0',\n });\n\n // 1. start-meeting\n server.tool(\n 'start-meeting',\n 'Start a new multi-agent meeting on a topic with agenda items',\n startMeetingSchema,\n startMeetingHandler,\n );\n\n // 2. get-meeting-status\n server.tool(\n 'get-meeting-status',\n 'Get the status of a specific meeting or all active meetings',\n getMeetingStatusSchema,\n getMeetingStatusHandler,\n );\n\n // 3. get-minutes\n server.tool(\n 'get-minutes',\n 'Retrieve meeting minutes in full, summary, or tasks-only format',\n getMinutesSchema,\n getMinutesHandler,\n );\n\n // 4. compact-minutes\n server.tool(\n 'compact-minutes',\n 'Compact meeting minutes into a structured, department-assigned task list',\n compactMinutesSchema,\n compactMinutesHandler,\n );\n\n // 5. execute-tasks\n server.tool(\n 'execute-tasks',\n 'Execute tasks from compacted minutes by spawning workers per department',\n executeTasksSchema,\n executeTasksHandler,\n );\n\n // 6. get-agent-tree\n server.tool(\n 'get-agent-tree',\n 'Return the full agent hierarchy tree',\n getAgentTreeHandler,\n );\n\n // 7. respond-to-mention\n server.tool(\n 'respond-to-mention',\n 'Respond to a pending @mention with a decision',\n respondToMentionSchema,\n respondToMentionHandler,\n );\n\n // 8. get-mentions\n server.tool(\n 'get-mentions',\n 'List @mentions filtered by status and/or meeting',\n getMentionsSchema,\n getMentionsHandler,\n );\n\n // 9. cancel-meeting\n server.tool(\n 'cancel-meeting',\n 'Cancel an active meeting and clean up its agents and workers',\n cancelMeetingSchema,\n cancelMeetingHandler,\n );\n\n // 10. list-meetings\n server.tool(\n 'list-meetings',\n 'List meetings with optional status filter and pagination',\n listMeetingsSchema,\n listMeetingsHandler,\n );\n\n // 11. get-task-report\n server.tool(\n 'get-task-report',\n 'Generate a task execution report for a meeting with per-department breakdown',\n getTaskReportSchema,\n getTaskReportHandler,\n );\n\n // 12. create-capability\n server.tool(\n 'create-capability',\n 'Create a new extension capability (hook, skill, command, asset, or loop)',\n createCapabilitySchema,\n createCapabilityHandler,\n );\n\n // 13. get-cost-summary\n server.tool(\n 'get-cost-summary',\n 'Get cost summary for a specific meeting or overall across all meetings',\n getCostSummarySchema,\n getCostSummaryHandler,\n );\n\n // 14. chain-meeting\n server.tool(\n 'chain-meeting',\n 'Start a new meeting chained from a previous meeting, using its minutes as context',\n chainMeetingSchema,\n chainMeetingHandler,\n );\n\n return server;\n}\n","import { z } from 'zod';\nimport { Orchestrator } from '../orchestrator/orchestrator.js';\nimport type { Department } from '../types/index.js';\n\nexport const startMeetingSchema = {\n topic: z.string().describe('Meeting topic'),\n agenda: z.array(z.string()).describe('Agenda items'),\n departments: z\n .array(z.string())\n .optional()\n .describe('Specific departments to invite'),\n};\n\nexport async function startMeetingHandler({\n topic,\n agenda,\n departments,\n}: {\n topic: string;\n agenda: string[];\n departments?: string[];\n}): Promise<{ content: { type: 'text'; text: string }[]; isError?: boolean }> {\n try {\n const orchestrator = new Orchestrator();\n const meetingId = await orchestrator.startMeeting({\n topic,\n agenda,\n departments: departments as Department[] | undefined,\n });\n\n const result = {\n meetingId,\n status: 'started',\n topic,\n agenda,\n departments: departments ?? orchestrator.selectLeaders(topic, agenda),\n };\n\n return {\n content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],\n };\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n return {\n content: [\n { type: 'text', text: JSON.stringify({ error: message }, null, 2) },\n ],\n isError: true,\n };\n }\n}\n","import { v4 as uuidv4 } from 'uuid';\nimport type {\n Department,\n Meeting,\n MentionRecord,\n AgentNode,\n} from '../types/index.js';\nimport {\n createMeeting,\n updateMeeting,\n getMeeting,\n listMeetings,\n listPendingMentions,\n getAgentTree,\n getMinutesByMeeting,\n} from '../storage/index.js';\nimport type { AgentTreeNode } from '../storage/index.js';\nimport { LeaderPool } from './leader-pool.js';\nimport { MeetingRunner } from './meeting-runner.js';\nimport { eventBus } from './event-bus.js';\nimport { logger } from '../utils/logger.js';\nimport { analyzeProject, formatProjectContext } from '../agents/project-analyzer.js';\n\n// ---------------------------------------------------------------------------\n// Keyword maps for leader selection heuristics\n// ---------------------------------------------------------------------------\n\nconst DEPARTMENT_KEYWORDS: Record<Department, string[]> = {\n architecture: [\n 'architecture', 'design', 'schema', 'api', 'data model', 'module',\n 'interface', 'contract', 'coupling', 'dependency graph', 'adr',\n 'system design', 'blueprint', 'data flow',\n ],\n engineering: [\n 'code', 'implement', 'build', 'feature', 'bug', 'fix', 'refactor',\n 'develop', 'function', 'class', 'module', 'write', 'create',\n 'modify', 'update', 'delete', 'crud', 'endpoint', 'migration',\n ],\n qa: [\n 'test', 'quality', 'security', 'performance', 'audit', 'coverage',\n 'regression', 'benchmark', 'vulnerability', 'pen test', 'lint',\n 'assertion', 'e2e', 'integration test', 'unit test',\n ],\n product: [\n 'requirements', 'user', 'story', 'priority', 'acceptance criteria',\n 'user flow', 'stakeholder', 'roadmap', 'scope', 'use case',\n 'persona', 'mvp', 'specification',\n ],\n research: [\n 'research', 'explore', 'investigate', 'search', 'analyze', 'find',\n 'discover', 'benchmark', 'compare', 'survey', 'documentation',\n 'reference', 'existing code',\n ],\n};\n\n// ---------------------------------------------------------------------------\n// StartMeeting options\n// ---------------------------------------------------------------------------\n\nexport interface StartMeetingOptions {\n topic: string;\n agenda: string[];\n departments?: Department[];\n}\n\n// ---------------------------------------------------------------------------\n// Orchestrator status\n// ---------------------------------------------------------------------------\n\nexport interface OrchestratorStatus {\n activeMeetings: Meeting[];\n pendingMentions: MentionRecord[];\n agentTree: AgentTreeNode | null;\n}\n\n// ---------------------------------------------------------------------------\n// Orchestrator\n// ---------------------------------------------------------------------------\n\nexport class Orchestrator {\n private readonly leaderPool = new LeaderPool();\n\n /**\n * Internal ID for the orchestrator \"agent\". Used as the meeting initiator\n * and as the root of the agent tree.\n */\n private readonly orchestratorId: string;\n\n constructor(orchestratorId?: string) {\n this.orchestratorId = orchestratorId ?? 'orchestrator-root';\n }\n\n // ---- leader selection ---------------------------------------------------\n\n /**\n * Analyse a topic and agenda to determine which department leaders should\n * be convened for a meeting.\n *\n * Uses keyword-based heuristics:\n * - Matches topic + agenda text against per-department keyword lists.\n * - Scores each department by the number of keyword hits.\n * - Selects departments with at least one hit.\n * - Falls back to engineering + architecture for complex topics (multiple\n * agenda items) or engineering alone for simple ones.\n */\n selectLeaders(topic: string, agenda: string[]): Department[] {\n const corpus = [topic, ...agenda].join(' ').toLowerCase();\n\n const scores = new Map<Department, number>();\n\n for (const [dept, keywords] of Object.entries(DEPARTMENT_KEYWORDS) as [Department, string[]][]) {\n let score = 0;\n for (const kw of keywords) {\n if (corpus.includes(kw)) {\n score++;\n }\n }\n if (score > 0) {\n scores.set(dept, score);\n }\n }\n\n if (scores.size === 0) {\n // Fallback: complex topics (3+ agenda items) get architecture + engineering;\n // simple ones get engineering only.\n if (agenda.length >= 3) {\n logger.debug('No keyword matches; defaulting to architecture + engineering (complex topic)', {\n meetingId: topic,\n });\n return ['architecture', 'engineering'];\n }\n logger.debug('No keyword matches; defaulting to engineering only (simple topic)', {\n meetingId: topic,\n });\n return ['engineering'];\n }\n\n // Sort by score descending and take all with hits\n const selected = [...scores.entries()]\n .sort((a, b) => b[1] - a[1])\n .map(([dept]) => dept);\n\n logger.debug(`Selected departments: ${selected.join(', ')}`, { meetingId: topic });\n\n return selected;\n }\n\n // ---- start meeting ------------------------------------------------------\n\n /**\n * Start a new meeting.\n *\n * 1. Selects departments (if not provided).\n * 2. Creates the meeting record in SQLite.\n * 3. Spawns leaders via the LeaderPool.\n * 4. Runs the MeetingRunner lifecycle (opening -> discussion -> synthesis -> minutes).\n * 5. Deactivates leaders after completion.\n *\n * Returns the meeting ID.\n */\n async startMeeting(opts: StartMeetingOptions & { previousMeetingId?: string | null }): Promise<string> {\n const { topic, agenda } = opts;\n const departments = opts.departments ?? this.selectLeaders(topic, agenda);\n\n logger.info(`Starting meeting: \"${topic}\" with departments: [${departments.join(', ')}]`);\n\n // 0. Analyse the current working directory for project context\n let projectContext: string | undefined;\n try {\n const analysis = await analyzeProject(process.cwd());\n projectContext = formatProjectContext(analysis);\n logger.debug('Project analysis complete', { meetingId: topic });\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n logger.warn(`Project analysis failed (proceeding without context): ${msg}`);\n }\n\n // 1. Create the meeting record\n const meetingId = uuidv4();\n const meeting = createMeeting({\n id: meetingId,\n topic,\n agenda,\n participantIds: [], // Will be filled in after leader spawning\n initiatedBy: this.orchestratorId,\n status: 'convening',\n phase: 'convening',\n startedAt: Date.now(),\n previousMeetingId: opts.previousMeetingId ?? null,\n });\n\n // 2. Spawn leaders\n const leaders: AgentNode[] = [];\n for (const dept of departments) {\n const leader = this.leaderPool.spawnLeader(dept, meetingId);\n leaders.push(leader);\n }\n\n // Update meeting with participant IDs\n updateMeeting(meetingId, {\n participantIds: leaders.map((l) => l.id),\n });\n\n // 3. Run the meeting (with project context for leader prompts)\n const runner = new MeetingRunner(meetingId, leaders, projectContext);\n\n try {\n await runner.run();\n } finally {\n // 4. Deactivate leaders regardless of success/failure\n for (const leader of leaders) {\n this.leaderPool.deactivateLeader(leader.id);\n }\n }\n\n return meetingId;\n }\n\n // ---- chain meeting -------------------------------------------------------\n\n /**\n * Chain a new meeting from the output of a previous meeting.\n *\n * Loads minutes from the previous meeting and includes them as context for\n * the new meeting topic. The new meeting's `previousMeetingId` is set for\n * traceability.\n */\n async chainMeeting(opts: {\n previousMeetingId: string;\n topic: string;\n agenda: string[];\n departments?: Department[];\n }): Promise<string> {\n const previousMeeting = getMeeting(opts.previousMeetingId);\n if (!previousMeeting) {\n throw new Error(`Previous meeting not found: ${opts.previousMeetingId}`);\n }\n\n const previousMinutes = getMinutesByMeeting(opts.previousMeetingId);\n if (!previousMinutes) {\n throw new Error(`No minutes found for previous meeting: ${opts.previousMeetingId}`);\n }\n\n // Prepend the previous meeting context to the topic\n const contextPrefix =\n `[Chained from meeting \"${previousMeeting.topic}\" (${opts.previousMeetingId})]\\n\\n` +\n `--- Previous Meeting Minutes ---\\n${previousMinutes.content}\\n--- End Previous Minutes ---\\n\\n`;\n\n const enrichedTopic = contextPrefix + opts.topic;\n\n logger.info(\n `Chaining meeting from \"${previousMeeting.topic}\" -> \"${opts.topic}\"`,\n { meetingId: opts.previousMeetingId },\n );\n\n return this.startMeeting({\n topic: enrichedTopic,\n agenda: opts.agenda,\n departments: opts.departments,\n previousMeetingId: opts.previousMeetingId,\n });\n }\n\n // ---- status -------------------------------------------------------------\n\n /**\n * Return a summary of all active meetings, pending @mentions, and the\n * current agent tree.\n */\n getStatus(): OrchestratorStatus {\n // Active meetings: anything not completed/cancelled/failed\n const allMeetings = listMeetings();\n const activeMeetings = allMeetings.filter(\n (m) => !['completed', 'cancelled', 'failed', 'reported', 'compacted'].includes(m.status),\n );\n\n // Pending @mentions across all meetings\n const pendingMentions = listPendingMentions();\n\n // Agent tree rooted at the orchestrator (may be null if no agents yet)\n const agentTree = getAgentTree(this.orchestratorId);\n\n return {\n activeMeetings,\n pendingMentions,\n agentTree,\n };\n }\n\n // ---- accessors ----------------------------------------------------------\n\n /** The leader pool used by this orchestrator instance. */\n getLeaderPool(): LeaderPool {\n return this.leaderPool;\n }\n\n /** The orchestrator's agent ID. */\n getId(): string {\n return this.orchestratorId;\n }\n}\n","import { v4 as uuidv4 } from 'uuid';\nimport { getDb } from './db.js';\nimport type { AgentNode, AgentTier, AgentStatus, Department } from '../types/index.js';\n\ninterface AgentRow {\n id: string;\n tier: string;\n role: string;\n department: string;\n parent_id: string | null;\n meeting_id: string | null;\n status: string;\n current_task: string | null;\n session_id: string | null;\n spawned_at: number;\n completed_at: number | null;\n cost_usd: number;\n}\n\nfunction rowToAgent(row: AgentRow): AgentNode {\n return {\n id: row.id,\n tier: row.tier as AgentTier,\n role: row.role,\n department: row.department as Department,\n parentId: row.parent_id,\n meetingId: row.meeting_id,\n status: row.status as AgentStatus,\n currentTask: row.current_task,\n sessionId: row.session_id,\n spawnedAt: row.spawned_at,\n completedAt: row.completed_at,\n costUsd: row.cost_usd,\n };\n}\n\nexport function createAgent(\n agent: Omit<AgentNode, 'id' | 'spawnedAt' | 'completedAt' | 'costUsd'> & {\n id?: string;\n spawnedAt?: number;\n completedAt?: number | null;\n costUsd?: number;\n }\n): AgentNode {\n const db = getDb();\n const id = agent.id ?? uuidv4();\n const spawnedAt = agent.spawnedAt ?? Date.now();\n const completedAt = agent.completedAt ?? null;\n const costUsd = agent.costUsd ?? 0;\n\n db.prepare(\n `INSERT INTO agents (id, tier, role, department, parent_id, meeting_id, status, current_task, session_id, spawned_at, completed_at, cost_usd)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`\n ).run(\n id,\n agent.tier,\n agent.role,\n agent.department,\n agent.parentId,\n agent.meetingId,\n agent.status,\n agent.currentTask,\n agent.sessionId,\n spawnedAt,\n completedAt,\n costUsd\n );\n\n return {\n id,\n tier: agent.tier,\n role: agent.role,\n department: agent.department,\n parentId: agent.parentId,\n meetingId: agent.meetingId,\n status: agent.status,\n currentTask: agent.currentTask,\n sessionId: agent.sessionId,\n spawnedAt,\n completedAt,\n costUsd,\n };\n}\n\nexport function getAgent(id: string): AgentNode | null {\n const db = getDb();\n const row = db.prepare('SELECT * FROM agents WHERE id = ?').get(id) as AgentRow | undefined;\n return row ? rowToAgent(row) : null;\n}\n\nexport function updateAgent(\n id: string,\n updates: Partial<Omit<AgentNode, 'id'>>\n): AgentNode | null {\n const db = getDb();\n const existing = getAgent(id);\n if (!existing) return null;\n\n const fields: string[] = [];\n const values: unknown[] = [];\n\n if (updates.tier !== undefined) { fields.push('tier = ?'); values.push(updates.tier); }\n if (updates.role !== undefined) { fields.push('role = ?'); values.push(updates.role); }\n if (updates.department !== undefined) { fields.push('department = ?'); values.push(updates.department); }\n if (updates.parentId !== undefined) { fields.push('parent_id = ?'); values.push(updates.parentId); }\n if (updates.meetingId !== undefined) { fields.push('meeting_id = ?'); values.push(updates.meetingId); }\n if (updates.status !== undefined) { fields.push('status = ?'); values.push(updates.status); }\n if (updates.currentTask !== undefined) { fields.push('current_task = ?'); values.push(updates.currentTask); }\n if (updates.sessionId !== undefined) { fields.push('session_id = ?'); values.push(updates.sessionId); }\n if (updates.spawnedAt !== undefined) { fields.push('spawned_at = ?'); values.push(updates.spawnedAt); }\n if (updates.completedAt !== undefined) { fields.push('completed_at = ?'); values.push(updates.completedAt); }\n if (updates.costUsd !== undefined) { fields.push('cost_usd = ?'); values.push(updates.costUsd); }\n\n if (fields.length === 0) return existing;\n\n values.push(id);\n db.prepare(`UPDATE agents SET ${fields.join(', ')} WHERE id = ?`).run(...values);\n\n return getAgent(id);\n}\n\nexport function listAgentsByMeeting(meetingId: string): AgentNode[] {\n const db = getDb();\n const rows = db\n .prepare('SELECT * FROM agents WHERE meeting_id = ?')\n .all(meetingId) as AgentRow[];\n return rows.map(rowToAgent);\n}\n\nexport function listAgentsByParent(parentId: string): AgentNode[] {\n const db = getDb();\n const rows = db\n .prepare('SELECT * FROM agents WHERE parent_id = ?')\n .all(parentId) as AgentRow[];\n return rows.map(rowToAgent);\n}\n\nexport interface AgentTreeNode extends AgentNode {\n children: AgentTreeNode[];\n}\n\nexport function getAgentTree(rootId: string): AgentTreeNode | null {\n const agent = getAgent(rootId);\n if (!agent) return null;\n\n const children = listAgentsByParent(rootId);\n const treeNode: AgentTreeNode = {\n ...agent,\n children: children\n .map((child) => getAgentTree(child.id))\n .filter((node): node is AgentTreeNode => node !== null),\n };\n\n return treeNode;\n}\n","import { v4 as uuidv4 } from 'uuid';\nimport { getDb } from './db.js';\nimport type { Meeting, MeetingStatus, MeetingPhase } from '../types/index.js';\n\ninterface MeetingRow {\n id: string;\n topic: string;\n agenda: string;\n participant_ids: string;\n status: string;\n phase: string;\n started_at: number | null;\n completed_at: number | null;\n initiated_by: string;\n previous_meeting_id?: string | null;\n}\n\n/** Ensure the previous_meeting_id column exists (backward-compat migration). */\nfunction ensurePreviousMeetingIdColumn(): void {\n const db = getDb();\n // PRAGMA table_info returns rows for each column; check if the column exists.\n const cols = db.prepare(\"PRAGMA table_info('meetings')\").all() as Array<{ name: string }>;\n const hasColumn = cols.some((c) => c.name === 'previous_meeting_id');\n if (!hasColumn) {\n db.exec('ALTER TABLE meetings ADD COLUMN previous_meeting_id TEXT DEFAULT NULL');\n }\n}\n\nlet columnChecked = false;\n\nfunction rowToMeeting(row: MeetingRow): Meeting {\n return {\n id: row.id,\n topic: row.topic,\n agenda: JSON.parse(row.agenda) as string[],\n participantIds: JSON.parse(row.participant_ids) as string[],\n status: row.status as MeetingStatus,\n phase: row.phase as MeetingPhase,\n startedAt: row.started_at,\n completedAt: row.completed_at,\n initiatedBy: row.initiated_by,\n previousMeetingId: row.previous_meeting_id ?? null,\n };\n}\n\nexport function createMeeting(\n meeting: Omit<Meeting, 'id' | 'status' | 'phase' | 'startedAt' | 'completedAt' | 'previousMeetingId'> & {\n id?: string;\n status?: MeetingStatus;\n phase?: MeetingPhase;\n startedAt?: number | null;\n completedAt?: number | null;\n previousMeetingId?: string | null;\n }\n): Meeting {\n if (!columnChecked) {\n ensurePreviousMeetingIdColumn();\n columnChecked = true;\n }\n\n const db = getDb();\n const id = meeting.id ?? uuidv4();\n const status = meeting.status ?? 'pending';\n const phase = meeting.phase ?? 'orchestrator-phase';\n const startedAt = meeting.startedAt ?? null;\n const completedAt = meeting.completedAt ?? null;\n const previousMeetingId = meeting.previousMeetingId ?? null;\n\n db.prepare(\n `INSERT INTO meetings (id, topic, agenda, participant_ids, status, phase, started_at, completed_at, initiated_by, previous_meeting_id)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`\n ).run(\n id,\n meeting.topic,\n JSON.stringify(meeting.agenda),\n JSON.stringify(meeting.participantIds),\n status,\n phase,\n startedAt,\n completedAt,\n meeting.initiatedBy,\n previousMeetingId\n );\n\n return {\n id,\n topic: meeting.topic,\n agenda: meeting.agenda,\n participantIds: meeting.participantIds,\n status,\n phase,\n startedAt,\n completedAt,\n initiatedBy: meeting.initiatedBy,\n previousMeetingId,\n };\n}\n\nexport function getMeeting(id: string): Meeting | null {\n if (!columnChecked) {\n ensurePreviousMeetingIdColumn();\n columnChecked = true;\n }\n\n const db = getDb();\n const row = db.prepare('SELECT * FROM meetings WHERE id = ?').get(id) as MeetingRow | undefined;\n return row ? rowToMeeting(row) : null;\n}\n\nexport function updateMeeting(\n id: string,\n updates: Partial<Omit<Meeting, 'id'>>\n): Meeting | null {\n const db = getDb();\n const existing = getMeeting(id);\n if (!existing) return null;\n\n const fields: string[] = [];\n const values: unknown[] = [];\n\n if (updates.topic !== undefined) { fields.push('topic = ?'); values.push(updates.topic); }\n if (updates.agenda !== undefined) { fields.push('agenda = ?'); values.push(JSON.stringify(updates.agenda)); }\n if (updates.participantIds !== undefined) { fields.push('participant_ids = ?'); values.push(JSON.stringify(updates.participantIds)); }\n if (updates.status !== undefined) { fields.push('status = ?'); values.push(updates.status); }\n if (updates.phase !== undefined) { fields.push('phase = ?'); values.push(updates.phase); }\n if (updates.startedAt !== undefined) { fields.push('started_at = ?'); values.push(updates.startedAt); }\n if (updates.completedAt !== undefined) { fields.push('completed_at = ?'); values.push(updates.completedAt); }\n if (updates.initiatedBy !== undefined) { fields.push('initiated_by = ?'); values.push(updates.initiatedBy); }\n if (updates.previousMeetingId !== undefined) { fields.push('previous_meeting_id = ?'); values.push(updates.previousMeetingId); }\n\n if (fields.length === 0) return existing;\n\n values.push(id);\n db.prepare(`UPDATE meetings SET ${fields.join(', ')} WHERE id = ?`).run(...values);\n\n return getMeeting(id);\n}\n\nexport function listMeetings(statusFilter?: MeetingStatus): Meeting[] {\n if (!columnChecked) {\n ensurePreviousMeetingIdColumn();\n columnChecked = true;\n }\n\n const db = getDb();\n let rows: MeetingRow[];\n\n if (statusFilter) {\n rows = db\n .prepare('SELECT * FROM meetings WHERE status = ? ORDER BY started_at DESC')\n .all(statusFilter) as MeetingRow[];\n } else {\n rows = db\n .prepare('SELECT * FROM meetings ORDER BY started_at DESC')\n .all() as MeetingRow[];\n }\n\n return rows.map(rowToMeeting);\n}\n","import { v4 as uuidv4 } from 'uuid';\nimport { getDb } from './db.js';\nimport type { WorkerRecord, WorkerStatus, TaskType } from '../types/index.js';\n\ninterface WorkerRow {\n id: string;\n leader_id: string;\n meeting_id: string;\n task_description: string;\n task_type: string | null;\n status: string;\n input_context: string | null;\n output_result: string | null;\n error_message: string | null;\n dependencies: string;\n spawned_at: number;\n completed_at: number | null;\n cost_usd: number;\n}\n\nfunction rowToWorker(row: WorkerRow): WorkerRecord {\n return {\n id: row.id,\n leaderId: row.leader_id,\n meetingId: row.meeting_id,\n taskDescription: row.task_description,\n taskType: row.task_type as TaskType | null,\n status: row.status as WorkerStatus,\n inputContext: row.input_context,\n outputResult: row.output_result,\n errorMessage: row.error_message,\n dependencies: JSON.parse(row.dependencies) as string[],\n spawnedAt: row.spawned_at,\n completedAt: row.completed_at,\n costUsd: row.cost_usd,\n };\n}\n\nexport function createWorker(\n worker: Omit<WorkerRecord, 'id' | 'status' | 'spawnedAt' | 'completedAt' | 'costUsd'> & {\n id?: string;\n status?: WorkerStatus;\n spawnedAt?: number;\n completedAt?: number | null;\n costUsd?: number;\n }\n): WorkerRecord {\n const db = getDb();\n const id = worker.id ?? uuidv4();\n const status = worker.status ?? 'pending';\n const spawnedAt = worker.spawnedAt ?? Date.now();\n const completedAt = worker.completedAt ?? null;\n const costUsd = worker.costUsd ?? 0;\n\n db.prepare(\n `INSERT INTO workers (id, leader_id, meeting_id, task_description, task_type, status, input_context, output_result, error_message, dependencies, spawned_at, completed_at, cost_usd)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`\n ).run(\n id,\n worker.leaderId,\n worker.meetingId,\n worker.taskDescription,\n worker.taskType,\n status,\n worker.inputContext,\n worker.outputResult,\n worker.errorMessage,\n JSON.stringify(worker.dependencies),\n spawnedAt,\n completedAt,\n costUsd\n );\n\n return {\n id,\n leaderId: worker.leaderId,\n meetingId: worker.meetingId,\n taskDescription: worker.taskDescription,\n taskType: worker.taskType,\n status,\n inputContext: worker.inputContext,\n outputResult: worker.outputResult,\n errorMessage: worker.errorMessage,\n dependencies: worker.dependencies,\n spawnedAt,\n completedAt,\n costUsd,\n };\n}\n\nexport function getWorker(id: string): WorkerRecord | null {\n const db = getDb();\n const row = db.prepare('SELECT * FROM workers WHERE id = ?').get(id) as WorkerRow | undefined;\n return row ? rowToWorker(row) : null;\n}\n\nexport function updateWorker(\n id: string,\n updates: Partial<Omit<WorkerRecord, 'id'>>\n): WorkerRecord | null {\n const db = getDb();\n const existing = getWorker(id);\n if (!existing) return null;\n\n const fields: string[] = [];\n const values: unknown[] = [];\n\n if (updates.leaderId !== undefined) { fields.push('leader_id = ?'); values.push(updates.leaderId); }\n if (updates.meetingId !== undefined) { fields.push('meeting_id = ?'); values.push(updates.meetingId); }\n if (updates.taskDescription !== undefined) { fields.push('task_description = ?'); values.push(updates.taskDescription); }\n if (updates.taskType !== undefined) { fields.push('task_type = ?'); values.push(updates.taskType); }\n if (updates.status !== undefined) { fields.push('status = ?'); values.push(updates.status); }\n if (updates.inputContext !== undefined) { fields.push('input_context = ?'); values.push(updates.inputContext); }\n if (updates.outputResult !== undefined) { fields.push('output_result = ?'); values.push(updates.outputResult); }\n if (updates.errorMessage !== undefined) { fields.push('error_message = ?'); values.push(updates.errorMessage); }\n if (updates.dependencies !== undefined) { fields.push('dependencies = ?'); values.push(JSON.stringify(updates.dependencies)); }\n if (updates.spawnedAt !== undefined) { fields.push('spawned_at = ?'); values.push(updates.spawnedAt); }\n if (updates.completedAt !== undefined) { fields.push('completed_at = ?'); values.push(updates.completedAt); }\n if (updates.costUsd !== undefined) { fields.push('cost_usd = ?'); values.push(updates.costUsd); }\n\n if (fields.length === 0) return existing;\n\n values.push(id);\n db.prepare(`UPDATE workers SET ${fields.join(', ')} WHERE id = ?`).run(...values);\n\n return getWorker(id);\n}\n\nexport function listWorkersByLeader(leaderId: string): WorkerRecord[] {\n const db = getDb();\n const rows = db\n .prepare('SELECT * FROM workers WHERE leader_id = ? ORDER BY spawned_at ASC')\n .all(leaderId) as WorkerRow[];\n return rows.map(rowToWorker);\n}\n","import { v4 as uuidv4 } from 'uuid';\nimport { getDb } from './db.js';\nimport type { MentionRecord, MentionUrgency, MentionStatus, MentionOption } from '../types/index.js';\n\ninterface MentionRow {\n id: string;\n meeting_id: string;\n agenda_item: string | null;\n summary: string;\n options: string;\n urgency: string;\n status: string;\n user_decision: string | null;\n user_reasoning: string | null;\n created_at: number;\n resolved_at: number | null;\n}\n\nfunction rowToMention(row: MentionRow): MentionRecord {\n return {\n id: row.id,\n meetingId: row.meeting_id,\n agendaItem: row.agenda_item,\n summary: row.summary,\n options: JSON.parse(row.options) as MentionOption[],\n urgency: row.urgency as MentionUrgency,\n status: row.status as MentionStatus,\n userDecision: row.user_decision,\n userReasoning: row.user_reasoning,\n createdAt: row.created_at,\n resolvedAt: row.resolved_at,\n };\n}\n\nexport function createMention(\n mention: Omit<MentionRecord, 'id' | 'status' | 'createdAt' | 'resolvedAt'> & {\n id?: string;\n status?: MentionStatus;\n createdAt?: number;\n resolvedAt?: number | null;\n }\n): MentionRecord {\n const db = getDb();\n const id = mention.id ?? uuidv4();\n const status = mention.status ?? 'pending';\n const createdAt = mention.createdAt ?? Date.now();\n const resolvedAt = mention.resolvedAt ?? null;\n\n db.prepare(\n `INSERT INTO mentions (id, meeting_id, agenda_item, summary, options, urgency, status, user_decision, user_reasoning, created_at, resolved_at)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`\n ).run(\n id,\n mention.meetingId,\n mention.agendaItem,\n mention.summary,\n JSON.stringify(mention.options),\n mention.urgency,\n status,\n mention.userDecision,\n mention.userReasoning,\n createdAt,\n resolvedAt\n );\n\n return {\n id,\n meetingId: mention.meetingId,\n agendaItem: mention.agendaItem,\n summary: mention.summary,\n options: mention.options,\n urgency: mention.urgency,\n status,\n userDecision: mention.userDecision,\n userReasoning: mention.userReasoning,\n createdAt,\n resolvedAt,\n };\n}\n\nexport function getMention(id: string): MentionRecord | null {\n const db = getDb();\n const row = db.prepare('SELECT * FROM mentions WHERE id = ?').get(id) as MentionRow | undefined;\n return row ? rowToMention(row) : null;\n}\n\nexport function updateMention(\n id: string,\n updates: Partial<Omit<MentionRecord, 'id'>>\n): MentionRecord | null {\n const db = getDb();\n const existing = getMention(id);\n if (!existing) return null;\n\n const fields: string[] = [];\n const values: unknown[] = [];\n\n if (updates.meetingId !== undefined) { fields.push('meeting_id = ?'); values.push(updates.meetingId); }\n if (updates.agendaItem !== undefined) { fields.push('agenda_item = ?'); values.push(updates.agendaItem); }\n if (updates.summary !== undefined) { fields.push('summary = ?'); values.push(updates.summary); }\n if (updates.options !== undefined) { fields.push('options = ?'); values.push(JSON.stringify(updates.options)); }\n if (updates.urgency !== undefined) { fields.push('urgency = ?'); values.push(updates.urgency); }\n if (updates.status !== undefined) { fields.push('status = ?'); values.push(updates.status); }\n if (updates.userDecision !== undefined) { fields.push('user_decision = ?'); values.push(updates.userDecision); }\n if (updates.userReasoning !== undefined) { fields.push('user_reasoning = ?'); values.push(updates.userReasoning); }\n if (updates.createdAt !== undefined) { fields.push('created_at = ?'); values.push(updates.createdAt); }\n if (updates.resolvedAt !== undefined) { fields.push('resolved_at = ?'); values.push(updates.resolvedAt); }\n\n if (fields.length === 0) return existing;\n\n values.push(id);\n db.prepare(`UPDATE mentions SET ${fields.join(', ')} WHERE id = ?`).run(...values);\n\n return getMention(id);\n}\n\nexport function listPendingMentions(): MentionRecord[] {\n const db = getDb();\n const rows = db\n .prepare(\"SELECT * FROM mentions WHERE status = 'pending' ORDER BY created_at ASC\")\n .all() as MentionRow[];\n return rows.map(rowToMention);\n}\n\nexport function listMentionsByMeeting(meetingId: string): MentionRecord[] {\n const db = getDb();\n const rows = db\n .prepare('SELECT * FROM mentions WHERE meeting_id = ? ORDER BY created_at ASC')\n .all(meetingId) as MentionRow[];\n return rows.map(rowToMention);\n}\n","import { v4 as uuidv4 } from 'uuid';\nimport { getDb } from './db.js';\nimport type { MinutesRecord, MinutesFormat, ActionItem } from '../types/index.js';\n\ninterface MinutesRow {\n id: string;\n meeting_id: string;\n format: string;\n content: string;\n action_items: string;\n created_at: number;\n}\n\nfunction rowToMinutes(row: MinutesRow): MinutesRecord {\n return {\n id: row.id,\n meetingId: row.meeting_id,\n format: row.format as MinutesFormat,\n content: row.content,\n actionItems: JSON.parse(row.action_items) as ActionItem[],\n createdAt: row.created_at,\n };\n}\n\nexport function createMinutes(\n minutes: Omit<MinutesRecord, 'id' | 'createdAt'> & {\n id?: string;\n createdAt?: number;\n }\n): MinutesRecord {\n const db = getDb();\n const id = minutes.id ?? uuidv4();\n const createdAt = minutes.createdAt ?? Date.now();\n\n db.prepare(\n `INSERT INTO minutes (id, meeting_id, format, content, action_items, created_at)\n VALUES (?, ?, ?, ?, ?, ?)`\n ).run(\n id,\n minutes.meetingId,\n minutes.format,\n minutes.content,\n JSON.stringify(minutes.actionItems),\n createdAt\n );\n\n return {\n id,\n meetingId: minutes.meetingId,\n format: minutes.format,\n content: minutes.content,\n actionItems: minutes.actionItems,\n createdAt,\n };\n}\n\nexport function getMinutesByMeeting(meetingId: string): MinutesRecord | null {\n const db = getDb();\n const row = db\n .prepare('SELECT * FROM minutes WHERE meeting_id = ?')\n .get(meetingId) as MinutesRow | undefined;\n return row ? rowToMinutes(row) : null;\n}\n","import { getDb } from './db.js';\nimport type { ActionItem } from '../types/index.js';\n\ninterface MinutesRow {\n id: string;\n meeting_id: string;\n action_items: string;\n}\n\nexport function getTasksFromMinutes(meetingId: string): ActionItem[] {\n const db = getDb();\n const row = db\n .prepare('SELECT action_items FROM minutes WHERE meeting_id = ?')\n .get(meetingId) as Pick<MinutesRow, 'action_items'> | undefined;\n\n if (!row) return [];\n\n return JSON.parse(row.action_items) as ActionItem[];\n}\n\nexport function updateTaskInMinutes(\n meetingId: string,\n taskId: string,\n updates: Partial<Omit<ActionItem, 'id'>>\n): ActionItem | null {\n const db = getDb();\n const row = db\n .prepare('SELECT id, action_items FROM minutes WHERE meeting_id = ?')\n .get(meetingId) as Pick<MinutesRow, 'id' | 'action_items'> | undefined;\n\n if (!row) return null;\n\n const actionItems = JSON.parse(row.action_items) as ActionItem[];\n const index = actionItems.findIndex((item) => item.id === taskId);\n\n if (index === -1) return null;\n\n const updated: ActionItem = { ...actionItems[index], ...updates, id: taskId };\n actionItems[index] = updated;\n\n db.prepare('UPDATE minutes SET action_items = ? WHERE id = ?').run(\n JSON.stringify(actionItems),\n row.id\n );\n\n return updated;\n}\n","export type AgentTier = 'orchestrator' | 'leader' | 'worker';\n\nexport type AgentStatus =\n | 'idle'\n | 'in-meeting'\n | 'working'\n | 'spawning-workers'\n | 'aggregating'\n | 'waiting-for-user'\n | 'completed'\n | 'failed';\n\nexport type Department =\n | 'architecture'\n | 'engineering'\n | 'qa'\n | 'product'\n | 'research';\n\nexport type LeaderRole =\n | 'arch-leader'\n | 'eng-leader'\n | 'qa-leader'\n | 'pm-leader'\n | 'research-leader';\n\nexport type WorkerType =\n | 'schema-designer'\n | 'api-designer'\n | 'dependency-analyzer'\n | 'feature-dev'\n | 'bug-fixer'\n | 'refactorer'\n | 'test-writer'\n | 'test-runner'\n | 'security-auditor'\n | 'perf-tester'\n | 'requirements-analyzer'\n | 'user-flow-mapper'\n | 'code-explorer'\n | 'doc-searcher'\n | 'benchmark-runner'\n | 'minutes-writer'\n | 'compactor';\n\nexport interface AgentNode {\n id: string;\n tier: AgentTier;\n role: string;\n department: Department;\n parentId: string | null;\n meetingId: string | null;\n status: AgentStatus;\n currentTask: string | null;\n sessionId: string | null;\n spawnedAt: number;\n completedAt: number | null;\n costUsd: number;\n}\n\nexport interface AgentConfig {\n model: string;\n maxTurns: number;\n\n allowedTools: string[];\n}\n\nexport const TIER_CONFIGS: Record<AgentTier, Omit<AgentConfig, 'allowedTools'>> = {\n orchestrator: {\n model: 'claude-opus-4-6',\n maxTurns: 10,\n },\n leader: {\n model: 'claude-sonnet-4-6',\n maxTurns: 20,\n },\n worker: {\n model: 'claude-sonnet-4-6',\n maxTurns: 30,\n },\n};\n\nexport const DEPARTMENT_TOOLS: Record<Department, string[]> = {\n architecture: ['Read', 'Grep', 'Glob'],\n engineering: ['Read', 'Grep', 'Glob', 'Write', 'Edit', 'Bash'],\n qa: ['Read', 'Grep', 'Glob', 'Bash'],\n product: ['Read'],\n research: ['Read', 'Grep', 'Glob', 'WebSearch'],\n};\n","export type MeetingStatus =\n | 'pending'\n | 'convening'\n | 'opening'\n | 'discussion'\n | 'synthesis'\n | 'minutes-generation'\n | 'completed'\n | 'compacted'\n | 'executing'\n | 'aggregation'\n | 'reported'\n | 'waiting-for-user'\n | 'cancelled'\n | 'failed';\n\nexport type MeetingPhase =\n | 'orchestrator-phase'\n | 'convening'\n | 'opening'\n | 'discussion'\n | 'research-break'\n | 'synthesis'\n | 'minutes-generation';\n\nexport interface Meeting {\n id: string;\n topic: string;\n agenda: string[];\n participantIds: string[];\n status: MeetingStatus;\n phase: MeetingPhase;\n startedAt: number | null;\n completedAt: number | null;\n initiatedBy: string;\n previousMeetingId: string | null;\n}\n\nexport interface MeetingConfig {\n maxRoundsPerItem: number;\n convergenceThreshold: number;\n model: string;\n}\n\nexport const DEFAULT_MEETING_CONFIG: MeetingConfig = {\n maxRoundsPerItem: 3,\n convergenceThreshold: 0.8,\n model: 'claude-sonnet-4-6',\n};\n\nexport interface TranscriptEntry {\n id: number;\n meetingId: string;\n speakerId: string;\n speakerRole: string;\n agendaItemIndex: number;\n roundNumber: number;\n content: string;\n tokenCount: number;\n createdAt: number;\n}\n","import type { Department, LeaderRole, WorkerType } from '../types/index.js';\nimport { DEPARTMENT_TOOLS } from '../types/index.js';\n\n/** Full metadata for a department. */\nexport interface DepartmentInfo {\n name: Department;\n description: string;\n leaderRole: LeaderRole;\n workerTypes: WorkerType[];\n allowedTools: string[];\n}\n\nconst DEPARTMENT_REGISTRY: ReadonlyMap<Department, DepartmentInfo> = new Map<Department, DepartmentInfo>([\n [\n 'architecture',\n {\n name: 'architecture',\n description:\n 'Responsible for system design, schema definitions, API surface design, and dependency analysis. ' +\n 'The architecture department plans before code is written — it produces blueprints, not implementations.',\n leaderRole: 'arch-leader',\n workerTypes: ['schema-designer', 'api-designer', 'dependency-analyzer'],\n allowedTools: DEPARTMENT_TOOLS.architecture,\n },\n ],\n [\n 'engineering',\n {\n name: 'engineering',\n description:\n 'Responsible for writing, modifying, and refactoring production code. ' +\n 'Engineering owns feature development, bug fixes, and code quality improvements.',\n leaderRole: 'eng-leader',\n workerTypes: ['feature-dev', 'bug-fixer', 'refactorer'],\n allowedTools: DEPARTMENT_TOOLS.engineering,\n },\n ],\n [\n 'qa',\n {\n name: 'qa',\n description:\n 'Responsible for test creation, test execution, security auditing, and performance testing. ' +\n 'QA ensures deliverables meet acceptance criteria and do not introduce regressions.',\n leaderRole: 'qa-leader',\n workerTypes: ['test-writer', 'test-runner', 'security-auditor', 'perf-tester'],\n allowedTools: DEPARTMENT_TOOLS.qa,\n },\n ],\n [\n 'product',\n {\n name: 'product',\n description:\n 'Responsible for requirements analysis, user-flow mapping, and stakeholder alignment. ' +\n 'Product translates user intent into well-scoped, actionable requirements for other departments.',\n leaderRole: 'pm-leader',\n workerTypes: ['requirements-analyzer', 'user-flow-mapper'],\n allowedTools: DEPARTMENT_TOOLS.product,\n },\n ],\n [\n 'research',\n {\n name: 'research',\n description:\n 'Responsible for codebase exploration, documentation search, benchmarking, and knowledge gathering. ' +\n 'Research produces facts and context that inform decisions made by other departments.',\n leaderRole: 'research-leader',\n workerTypes: ['code-explorer', 'doc-searcher', 'benchmark-runner'],\n allowedTools: DEPARTMENT_TOOLS.research,\n },\n ],\n]);\n\n/** Reverse lookup: leader role → department. */\nconst ROLE_TO_DEPARTMENT: ReadonlyMap<LeaderRole, Department> = new Map<LeaderRole, Department>(\n [...DEPARTMENT_REGISTRY.values()].map((d) => [d.leaderRole, d.name]),\n);\n\n/**\n * Get the full metadata for a single department.\n * Throws if the department key is unknown.\n */\nexport function getDepartment(dept: Department): DepartmentInfo {\n const info = DEPARTMENT_REGISTRY.get(dept);\n if (!info) {\n throw new Error(`Unknown department: ${dept}`);\n }\n return info;\n}\n\n/**\n * Return metadata for every registered department.\n */\nexport function getAllDepartments(): DepartmentInfo[] {\n return [...DEPARTMENT_REGISTRY.values()];\n}\n\n/**\n * Resolve a leader role back to its owning department.\n * Throws if the role is unknown.\n */\nexport function getDepartmentForRole(role: LeaderRole): Department {\n const dept = ROLE_TO_DEPARTMENT.get(role);\n if (dept === undefined) {\n throw new Error(`Unknown leader role: ${role}`);\n }\n return dept;\n}\n","import { EventEmitter } from 'node:events';\nimport type { AgentEvent, DashboardEvent } from '../types/index.js';\n\n// ---------------------------------------------------------------------------\n// Typed event map\n// ---------------------------------------------------------------------------\n\n/**\n * Events emitted by the internal event bus.\n *\n * - `agent_event` — individual agent lifecycle events (spawned, destroyed, state change, etc.)\n * - `dashboard` — full dashboard payloads (snapshot or delta) intended for the WebSocket dashboard.\n */\nexport interface EventBusEvents {\n agent_event: [event: AgentEvent];\n dashboard: [event: DashboardEvent];\n}\n\n// ---------------------------------------------------------------------------\n// EventBus class\n// ---------------------------------------------------------------------------\n\nclass EventBus {\n private readonly emitter = new EventEmitter();\n\n constructor() {\n // Allow a reasonable number of listeners (leaders + dashboard + internal consumers)\n this.emitter.setMaxListeners(50);\n }\n\n // ---- emit ---------------------------------------------------------------\n\n /**\n * Emit a single agent lifecycle event.\n *\n * The event is:\n * 1. Broadcast to all `agent_event` listeners.\n * 2. Wrapped in a `delta` dashboard event and broadcast to `dashboard` listeners.\n * 3. (Planned) Persisted to SQLite via the storage layer.\n */\n emitAgentEvent(event: AgentEvent): void {\n this.emitter.emit('agent_event', event);\n\n // Wrap in a delta for the dashboard\n const delta: DashboardEvent = {\n type: 'delta',\n timestamp: Date.now(),\n events: [event],\n };\n this.emitter.emit('dashboard', delta);\n\n // TODO: persist to SQLite once the storage layer is implemented\n // import { eventStore } from '../storage/event-store.js';\n // eventStore.persist(event);\n }\n\n /**\n * Emit a full dashboard snapshot (used on initial WebSocket connection).\n */\n emitDashboardSnapshot(snapshot: DashboardEvent): void {\n this.emitter.emit('dashboard', snapshot);\n }\n\n // ---- subscribe ----------------------------------------------------------\n\n on<K extends keyof EventBusEvents>(event: K, listener: (...args: EventBusEvents[K]) => void): void {\n this.emitter.on(event, listener as (...args: unknown[]) => void);\n }\n\n off<K extends keyof EventBusEvents>(event: K, listener: (...args: EventBusEvents[K]) => void): void {\n this.emitter.off(event, listener as (...args: unknown[]) => void);\n }\n\n once<K extends keyof EventBusEvents>(event: K, listener: (...args: EventBusEvents[K]) => void): void {\n this.emitter.once(event, listener as (...args: unknown[]) => void);\n }\n\n // ---- utility ------------------------------------------------------------\n\n removeAllListeners(event?: keyof EventBusEvents): void {\n if (event) {\n this.emitter.removeAllListeners(event);\n } else {\n this.emitter.removeAllListeners();\n }\n }\n\n listenerCount(event: keyof EventBusEvents): number {\n return this.emitter.listenerCount(event);\n }\n}\n\n// ---------------------------------------------------------------------------\n// Singleton export\n// ---------------------------------------------------------------------------\n\n/** Global event bus singleton for internal inter-agent communication. */\nexport const eventBus = new EventBus();\n","/**\n * Structured logger that writes to stderr.\n *\n * stdout is reserved for the MCP stdio transport, so all diagnostic output\n * goes to stderr to avoid corrupting the JSON-RPC stream.\n */\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport type LogLevel = 'debug' | 'info' | 'warn' | 'error';\n\nexport interface LogContext {\n meetingId?: string;\n agentId?: string;\n department?: string;\n [key: string]: unknown;\n}\n\ninterface LogEntry {\n timestamp: string;\n level: LogLevel;\n message: string;\n context?: LogContext;\n}\n\n// ---------------------------------------------------------------------------\n// Level ordering\n// ---------------------------------------------------------------------------\n\nconst LEVEL_PRIORITY: Record<LogLevel, number> = {\n debug: 0,\n info: 1,\n warn: 2,\n error: 3,\n};\n\n// ---------------------------------------------------------------------------\n// Logger class\n// ---------------------------------------------------------------------------\n\nclass Logger {\n private minLevel: LogLevel = 'info';\n\n /**\n * Set the minimum log level. Messages below this level are silently dropped.\n * Defaults to 'info'. Set to 'debug' for verbose output.\n */\n setLevel(level: LogLevel): void {\n this.minLevel = level;\n }\n\n getLevel(): LogLevel {\n return this.minLevel;\n }\n\n debug(message: string, context?: LogContext): void {\n this.log('debug', message, context);\n }\n\n info(message: string, context?: LogContext): void {\n this.log('info', message, context);\n }\n\n warn(message: string, context?: LogContext): void {\n this.log('warn', message, context);\n }\n\n error(message: string, context?: LogContext): void {\n this.log('error', message, context);\n }\n\n // -----------------------------------------------------------------------\n // Internal\n // -----------------------------------------------------------------------\n\n private log(level: LogLevel, message: string, context?: LogContext): void {\n if (LEVEL_PRIORITY[level] < LEVEL_PRIORITY[this.minLevel]) {\n return;\n }\n\n const entry: LogEntry = {\n timestamp: new Date().toISOString(),\n level,\n message,\n };\n\n if (context && Object.keys(context).length > 0) {\n entry.context = context;\n }\n\n // Write to stderr as a single JSON line for easy parsing\n process.stderr.write(JSON.stringify(entry) + '\\n');\n }\n}\n\n// ---------------------------------------------------------------------------\n// Singleton export\n// ---------------------------------------------------------------------------\n\n/** Global structured logger — writes to stderr to keep stdout clean for MCP. */\nexport const logger = new Logger();\n","import { v4 as uuidv4 } from 'uuid';\nimport type { AgentNode, Department } from '../types/index.js';\nimport { createAgent, updateAgent, listAgentsByMeeting } from '../storage/index.js';\nimport { getDepartment } from '../agents/departments.js';\nimport { eventBus } from './event-bus.js';\nimport { logger } from '../utils/logger.js';\n\n// ---------------------------------------------------------------------------\n// LeaderPool — manages leader agent lifecycles\n// ---------------------------------------------------------------------------\n\nexport class LeaderPool {\n /**\n * Active leaders keyed by their agent ID.\n * This is a fast in-memory index; the source of truth is SQLite.\n */\n private readonly activeLeaders = new Map<string, AgentNode>();\n\n // ---- spawn --------------------------------------------------------------\n\n /**\n * Spawn a new leader agent for the given department and meeting.\n *\n * Persists the agent to SQLite and emits an `agent_spawned` event on the\n * event bus.\n */\n spawnLeader(department: Department, meetingId: string): AgentNode {\n const deptInfo = getDepartment(department);\n\n const agent = createAgent({\n tier: 'leader',\n role: deptInfo.leaderRole,\n department,\n parentId: null, // The orchestrator is implicit; no stored orchestrator agent row yet.\n meetingId,\n status: 'in-meeting',\n currentTask: null,\n sessionId: null,\n });\n\n this.activeLeaders.set(agent.id, agent);\n\n logger.info(`Spawned leader: ${deptInfo.leaderRole}`, {\n agentId: agent.id,\n department,\n meetingId,\n });\n\n eventBus.emitAgentEvent({\n kind: 'agent_spawned',\n agentId: agent.id,\n agentType: 'leader',\n parentId: null,\n label: deptInfo.leaderRole,\n department,\n });\n\n return agent;\n }\n\n // ---- query --------------------------------------------------------------\n\n /**\n * Return all currently-active leaders assigned to a given meeting.\n *\n * Falls back to a SQLite query filtered by status so that leaders which were\n * deactivated out-of-band are excluded.\n */\n getLeadersForMeeting(meetingId: string): AgentNode[] {\n // Fast path: filter in-memory cache\n const fromCache = [...this.activeLeaders.values()].filter(\n (a) => a.meetingId === meetingId,\n );\n\n if (fromCache.length > 0) {\n return fromCache;\n }\n\n // Slow path: query storage (e.g. after a server restart)\n return listAgentsByMeeting(meetingId).filter(\n (a) => a.tier === 'leader' && a.status !== 'completed' && a.status !== 'failed',\n );\n }\n\n // ---- deactivate ---------------------------------------------------------\n\n /**\n * Mark a leader as completed and remove it from the in-memory cache.\n */\n deactivateLeader(leaderId: string): void {\n const leader = this.activeLeaders.get(leaderId);\n\n updateAgent(leaderId, {\n status: 'completed',\n completedAt: Date.now(),\n });\n\n this.activeLeaders.delete(leaderId);\n\n logger.info(`Deactivated leader: ${leaderId}`, {\n agentId: leaderId,\n department: leader?.department,\n });\n\n eventBus.emitAgentEvent({\n kind: 'agent_destroyed',\n agentId: leaderId,\n });\n }\n}\n","import type { Department } from '../types/index.js';\nimport { getDepartment } from './departments.js';\n\n// ---------------------------------------------------------------------------\n// Internal helpers\n// ---------------------------------------------------------------------------\n\nfunction rulesBlock(extraRules?: string[]): string {\n const base = [\n 'Never modify files outside the project root unless explicitly told to.',\n 'Never commit, push, or deploy without a confirmed user decision.',\n 'If you encounter ambiguity that could lead to significant rework, emit @USER_DECISION_NEEDED immediately rather than guessing.',\n 'Keep responses concise. Prefer structured output (lists, tables) over prose.',\n 'When delegating to workers, provide clear task descriptions with explicit acceptance criteria.',\n 'Respect the tool allowlist for your department — do not attempt to use tools you have not been granted.',\n 'Report cost and token usage whenever you complete a significant sub-task.',\n ];\n const rules = extraRules ? [...base, ...extraRules] : base;\n return rules.map((r, i) => `${i + 1}. ${r}`).join('\\n');\n}\n\nfunction meetingProtocol(): string {\n return `## MEETING PROTOCOL\n\nWhen participating in a meeting you MUST follow these rules:\n\n1. **Opening phase** — Listen to the agenda presented by the orchestrator. Acknowledge understanding. Surface any concerns or dependencies your department has regarding the agenda items.\n\n2. **Discussion phase** — Contribute your department's perspective on each agenda item. Be specific: reference files, modules, or prior decisions. If you disagree with another leader, state your reasoning clearly and propose an alternative.\n\n3. **When to emit @USER_DECISION_NEEDED** — Emit this tag ONLY when:\n - Two or more leaders have irreconcilable positions after a full discussion round.\n - A decision has significant cost, security, or architectural implications that exceed the meeting's delegated authority.\n - The user explicitly asked to be looped in on a particular topic.\n Include: a concise summary of the options, who supports each option, and your recommended default.\n\n4. **Synthesis phase** — Confirm or amend the proposed action items. Ensure your department's commitments are accurate and achievable.\n\n5. **Post-meeting** — Execute your assigned action items by spawning workers or performing lightweight tasks directly.`;\n}\n\nfunction workforceManagement(deptDescription: string, workerTypes: string[]): string {\n return `## WORKFORCE MANAGEMENT\n\nYou lead the department: ${deptDescription}\n\nAvailable worker types you can spawn: ${workerTypes.join(', ')}\n\n### When to spawn workers\n- Spawn workers for tasks that require focused execution (file changes, test runs, research).\n- Do NOT spawn workers for simple questions you can answer from context.\n- Prefer spawning multiple independent workers in parallel over sequential single-worker chains.\n\n### How to spawn workers\nWhen you decide a worker is needed, output a structured worker-spawn request:\n\\`\\`\\`\nSPAWN_WORKER:\n type: <worker-type>\n task: <one-line description>\n context: <relevant files, decisions, or constraints>\n acceptance_criteria:\n - <criterion 1>\n - <criterion 2>\n\\`\\`\\`\n\n### Aggregating results\nWhen workers complete, review their output:\n- If a worker succeeded — incorporate the result and move forward.\n- If a worker failed — diagnose the failure. Retry with adjusted instructions or escalate in the meeting.\n- Summarise aggregated results before reporting back to the meeting.`;\n}\n\n// ---------------------------------------------------------------------------\n// Per-role identity blocks\n// ---------------------------------------------------------------------------\n\nconst IDENTITIES: Record<string, string> = {\n 'arch-leader': `## IDENTITY\n\nYou are the **Architecture Leader**. You own system design decisions for this project.\n\nYour responsibilities:\n- Evaluate and propose system architecture (module boundaries, data flow, APIs).\n- Design database schemas and data models.\n- Analyse dependency graphs and flag coupling or circular-dependency risks.\n- Ensure new features fit the existing architecture; propose refactors when they do not.\n- Produce architecture decision records (ADRs) when significant choices are made.\n\nYou are a planner, not an implementer. You produce blueprints and hand implementation to Engineering.`,\n\n 'eng-leader': `## IDENTITY\n\nYou are the **Engineering Leader**. You own code quality and delivery for this project.\n\nYour responsibilities:\n- Break down approved designs into implementable tasks.\n- Assign coding work to feature-dev, bug-fixer, and refactorer workers.\n- Review worker output for correctness, style, and adherence to project conventions.\n- Coordinate with QA to ensure changes are testable.\n- Flag technical debt and propose refactoring when it reaches a threshold.\n\nYou write and ship code through your workers. You translate architecture into working software.`,\n\n 'qa-leader': `## IDENTITY\n\nYou are the **QA Leader**. You own quality assurance, testing strategy, and security posture.\n\nYour responsibilities:\n- Define test plans: unit tests, integration tests, and end-to-end flows.\n- Spawn test-writer workers to create tests for new or changed code.\n- Spawn test-runner workers to execute test suites and report results.\n- Spawn security-auditor workers when new dependencies or sensitive code paths are introduced.\n- Spawn perf-tester workers for performance-critical changes.\n- Block merges that lack adequate test coverage or have failing tests.\n\nYou are the project's quality gate. Nothing ships without your sign-off.`,\n\n 'pm-leader': `## IDENTITY\n\nYou are the **Product Leader**. You own requirements clarity and user-facing coherence.\n\nYour responsibilities:\n- Analyse user requests and translate them into structured requirements.\n- Map user flows to ensure feature completeness and good UX.\n- Prioritise work items when resources are limited.\n- Ensure the team is building what the user actually asked for, not what was assumed.\n- Write acceptance criteria that other departments can verify against.\n\nYou are the voice of the user inside the team. You bridge intent and implementation.`,\n\n 'research-leader': `## IDENTITY\n\nYou are the **Research Leader**. You own information gathering and knowledge synthesis.\n\nYour responsibilities:\n- Explore the existing codebase to answer questions from other departments.\n- Search documentation, READMEs, and external resources for relevant context.\n- Run benchmarks when quantitative data is needed for a decision.\n- Summarise findings in a structured, citable format.\n- Maintain a knowledge base of discovered facts about the project.\n\nYou provide the evidence base. Other departments make decisions; you supply the facts.`,\n};\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Build a full system prompt for a department leader.\n *\n * @param department The department this leader represents.\n * @param rules Optional extra rules to append to the default rule set.\n * @returns A complete system prompt string.\n */\nexport function getLeaderSystemPrompt(\n department: Department,\n rules?: string[],\n projectContext?: string,\n): string {\n const dept = getDepartment(department);\n const identity = IDENTITIES[dept.leaderRole];\n if (!identity) {\n throw new Error(`No identity prompt defined for leader role: ${dept.leaderRole}`);\n }\n\n const sections = [\n identity,\n meetingProtocol(),\n workforceManagement(dept.description, dept.workerTypes),\n `## RULES\\n\\n${rulesBlock(rules)}`,\n ];\n\n if (projectContext) {\n sections.push(projectContext);\n }\n\n return sections.join('\\n\\n');\n}\n","import type { AgentTier, AgentConfig } from '../types/index.js';\nimport { TIER_CONFIGS } from '../types/index.js';\n\n/**\n * Valid parent→child relationships in the agent hierarchy.\n *\n * orchestrator → leader → worker\n *\n * An orchestrator can spawn leaders. A leader can spawn workers.\n * No other parent→child combination is allowed.\n */\nconst VALID_HIERARCHY: ReadonlyMap<AgentTier, AgentTier> = new Map([\n ['orchestrator', 'leader'],\n ['leader', 'worker'],\n]);\n\n/**\n * Returns `true` when `parentTier` is allowed to spawn a child of `childTier`.\n *\n * Rules:\n * - orchestrator → leader ✔\n * - leader → worker ✔\n * - everything else ✘\n */\nexport function isValidParent(parentTier: AgentTier, childTier: AgentTier): boolean {\n return VALID_HIERARCHY.get(parentTier) === childTier;\n}\n\n/**\n * Look up the tier-level configuration (model, maxTurns).\n *\n * Returns a copy so callers can safely mutate the result without affecting\n * the shared config.\n */\nexport function getTierConfig(tier: AgentTier): Omit<AgentConfig, 'allowedTools'> {\n const config = TIER_CONFIGS[tier];\n if (!config) {\n throw new Error(`Unknown agent tier: ${tier}`);\n }\n return { ...config };\n}\n","import type { Department, WorkerType } from '../types/index.js';\n\n/** Options for building a worker system prompt. */\nexport interface WorkerPromptOptions {\n workerType: WorkerType;\n department: Department;\n task: string;\n context?: string;\n projectContext?: string;\n}\n\n// ---------------------------------------------------------------------------\n// Worker-type descriptions\n// ---------------------------------------------------------------------------\n\nconst WORKER_DESCRIPTIONS: Record<WorkerType, string> = {\n // Architecture workers\n 'schema-designer':\n 'You design database schemas and data models. Output CREATE TABLE statements, type definitions, or ERD descriptions.',\n 'api-designer':\n 'You design API surfaces — REST endpoints, RPC methods, or function signatures. Output OpenAPI snippets or typed interface definitions.',\n 'dependency-analyzer':\n 'You analyse project dependencies and module coupling. Output dependency graphs, circular-dependency reports, or upgrade recommendations.',\n\n // Engineering workers\n 'feature-dev':\n 'You implement new features by writing production code. Follow the project conventions. Output complete, working code changes.',\n 'bug-fixer':\n 'You diagnose and fix bugs. Read the relevant code, identify the root cause, and produce a minimal correct fix.',\n 'refactorer':\n 'You improve existing code without changing its behaviour. Focus on readability, performance, or reducing duplication.',\n\n // QA workers\n 'test-writer':\n 'You write test cases — unit, integration, or end-to-end. Ensure each test has a clear assertion and covers the acceptance criteria.',\n 'test-runner':\n 'You execute test suites and report results. Run commands, capture output, and summarise pass/fail counts and failures.',\n 'security-auditor':\n 'You audit code for security vulnerabilities — injection, auth issues, insecure dependencies, exposed secrets. Output a structured finding list.',\n 'perf-tester':\n 'You run performance tests and benchmarks. Measure response time, throughput, or resource usage and report quantitative results.',\n\n // Product workers\n 'requirements-analyzer':\n 'You analyse user requests and existing documentation to produce structured requirements with acceptance criteria.',\n 'user-flow-mapper':\n 'You trace user-facing flows through the system — from input to output — and document each step, decision point, and edge case.',\n\n // Research workers\n 'code-explorer':\n 'You explore the codebase to answer specific questions. Read files, trace call chains, and summarise your findings.',\n 'doc-searcher':\n 'You search documentation, READMEs, comments, and external references to find relevant information.',\n 'benchmark-runner':\n 'You run benchmarks and collect quantitative data. Output structured results with methodology notes.',\n\n // Cross-cutting workers\n 'minutes-writer':\n 'You write structured meeting minutes from a transcript. Output: summary, decisions, action items, and @mentions.',\n compactor:\n 'You compact long conversation transcripts into a shorter summary that preserves all decisions, action items, and open questions.',\n};\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Build a focused single-task system prompt for a worker agent.\n *\n * The prompt includes:\n * 1. Worker identity and capability description\n * 2. The specific task to perform\n * 3. Optional context (files, prior decisions, constraints)\n * 4. Output expectations and rules\n */\nexport function buildWorkerPrompt(opts: WorkerPromptOptions): string {\n const { workerType, department, task, context, projectContext } = opts;\n\n const description = WORKER_DESCRIPTIONS[workerType];\n if (!description) {\n throw new Error(`Unknown worker type: ${workerType}`);\n }\n\n const sections: string[] = [\n `## IDENTITY\n\nYou are a **${workerType}** worker in the **${department}** department.\n\n${description}`,\n\n `## TASK\n\n${task}`,\n ];\n\n if (context) {\n sections.push(`## CONTEXT\n\n${context}`);\n }\n\n if (projectContext) {\n sections.push(projectContext);\n }\n\n sections.push(`## OUTPUT RULES\n\n1. Stay focused on the single task above. Do not wander into unrelated work.\n2. If the task is impossible or blocked, explain why clearly and stop — do not produce partial or guessed output.\n3. Prefer structured output: code blocks, lists, tables.\n4. Include file paths (always absolute) when referencing code.\n5. When your task is complete, end with a brief summary of what you did and any caveats.\n6. Respect the tool allowlist for the ${department} department — do not attempt to use tools you have not been granted.\n7. Do not commit, push, or deploy. Your output will be reviewed by your leader before any permanent action is taken.`);\n\n return sections.join('\\n\\n');\n}\n","import type { AgentTier, Department, WorkerType, AgentConfig } from '../types/index.js';\nimport { DEPARTMENT_TOOLS } from '../types/index.js';\nimport { getTierConfig } from './tiers.js';\nimport { getLeaderSystemPrompt } from './leader-prompts.js';\nimport { buildWorkerPrompt } from './worker-prompts.js';\nimport { getDepartment } from './departments.js';\n\n// ---------------------------------------------------------------------------\n// Orchestrator system prompt\n// ---------------------------------------------------------------------------\n\nconst ORCHESTRATOR_SYSTEM_PROMPT = `## IDENTITY\n\nYou are the **Orchestrator** — a proxy and router, NOT a CEO. Your job is to receive the user's request, decompose it into department-level concerns, convene meetings, and route work to the appropriate leaders. You do not make product, architecture, or engineering decisions yourself.\n\n## CORE RESPONSIBILITIES\n\n1. **Request analysis** — When the user submits a request, determine which departments are relevant. Most requests involve 2-4 departments.\n\n2. **Meeting convening** — Create a meeting with an agenda derived from the request. Invite the relevant leaders. You chair the meeting but you do not dominate it.\n\n3. **Auto-routing** — For straightforward, single-department tasks (e.g., \"run the tests\"), skip the full meeting flow and route directly to the responsible leader.\n\n4. **@USER mentions** — When a leader emits @USER_DECISION_NEEDED during a meeting:\n - Pause the meeting.\n - Surface the decision to the user with full context (options, trade-offs, supporters).\n - Resume the meeting once the user responds.\n\n5. **Progress tracking** — Monitor worker completion events. Nudge leaders if a task is overdue or failed. Report final results back to the user.\n\n## RULES\n\n1. You are a facilitator. Do NOT override leader recommendations unless they conflict with an explicit user instruction.\n2. Keep your own token usage minimal — delegate analysis and execution to leaders and workers.\n3. Always preserve the user's exact wording when forwarding a request to a meeting.\n4. If the user's request is ambiguous, ask a clarifying question BEFORE convening a meeting.\n5. Never modify files, run tests, or execute code directly. All execution happens through workers spawned by leaders.\n6. When multiple departments disagree, facilitate resolution. Escalate to the user only when the team cannot converge after a full discussion round.\n7. After a meeting completes, provide the user with a concise summary: decisions made, action items, and any pending @USER items.\n8. Respect budget limits. If projected cost approaches the meeting budget, warn the user and request approval before proceeding.\n\n## DEPARTMENT OVERVIEW\n\nYou can route work to these departments:\n- **architecture** — System design, schemas, API surfaces, dependency analysis.\n- **engineering** — Feature implementation, bug fixes, refactoring.\n- **qa** — Testing, security audits, performance testing.\n- **product** — Requirements analysis, user-flow mapping, prioritisation.\n- **research** — Codebase exploration, documentation search, benchmarks.\n\n## OUTPUT FORMAT\n\nWhen you need to convene a meeting, output:\n\\`\\`\\`\nCONVENE_MEETING:\n topic: <meeting topic>\n agenda:\n - <item 1>\n - <item 2>\n departments:\n - <dept 1>\n - <dept 2>\n\\`\\`\\`\n\nWhen you route directly to a leader (no meeting), output:\n\\`\\`\\`\nDIRECT_ROUTE:\n department: <department>\n task: <task description>\n\\`\\`\\`\n`;\n\n// ---------------------------------------------------------------------------\n// Options\n// ---------------------------------------------------------------------------\n\nexport interface CreateAgentConfigOptions {\n tier: AgentTier;\n role: string;\n department: Department;\n task?: string;\n context?: string;\n}\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Build a complete agent configuration suitable for the Claude Agent SDK.\n *\n * - For **orchestrator**: uses the built-in orchestrator system prompt.\n * - For **leaders**: uses the department-specific leader prompt.\n * - For **workers**: uses the focused worker prompt builder.\n * - Research workers override the model to `claude-haiku-4-5` and cap budget at $0.10.\n */\nexport function createAgentConfig(opts: CreateAgentConfigOptions): AgentConfig {\n const { tier, role, department, task, context } = opts;\n\n // Base config from tier\n const tierCfg = getTierConfig(tier);\n\n // Determine allowed tools\n const allowedTools: string[] = [...(DEPARTMENT_TOOLS[department] ?? [])];\n\n // Build system prompt based on tier\n let systemPrompt: string;\n\n switch (tier) {\n case 'orchestrator': {\n systemPrompt = ORCHESTRATOR_SYSTEM_PROMPT;\n break;\n }\n\n case 'leader': {\n systemPrompt = getLeaderSystemPrompt(department);\n break;\n }\n\n case 'worker': {\n if (!task) {\n throw new Error('Worker agents require a task description');\n }\n systemPrompt = buildWorkerPrompt({\n workerType: role as WorkerType,\n department,\n task,\n context,\n });\n break;\n }\n\n default: {\n const _exhaustive: never = tier;\n throw new Error(`Unknown tier: ${_exhaustive}`);\n }\n }\n\n // Research workers use a lighter model\n const model = (tier === 'worker' && department === 'research')\n ? 'claude-haiku-4-5'\n : tierCfg.model;\n\n return {\n model,\n maxTurns: tierCfg.maxTurns,\n allowedTools,\n };\n}\n\n/**\n * Retrieve the orchestrator system prompt directly (useful for testing or\n * inspection without constructing a full config).\n */\nexport function getOrchestratorSystemPrompt(): string {\n return ORCHESTRATOR_SYSTEM_PROMPT;\n}\n","import { spawn } from 'node:child_process';\nimport { execSync } from 'node:child_process';\nimport type { AgentConfig } from '../types/index.js';\nimport { logger } from '../utils/logger.js';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport interface InvokeOptions {\n prompt: string;\n systemPrompt: string;\n allowedTools: string[];\n maxTurns: number;\n cwd?: string;\n /** Timeout in milliseconds. Defaults to 300_000 (5 min). */\n timeoutMs?: number;\n}\n\nexport interface InvokeResult {\n success: boolean;\n output: string;\n error?: string;\n costUsd?: number;\n}\n\n// ---------------------------------------------------------------------------\n// Mock mode detection\n// ---------------------------------------------------------------------------\n\nlet _claudeAvailable: boolean | null = null;\n\n/**\n * Check whether the `claude` CLI binary is available on PATH.\n * Result is cached after the first check.\n */\nfunction isClaudeAvailable(): boolean {\n if (_claudeAvailable !== null) return _claudeAvailable;\n\n try {\n execSync('which claude', { stdio: 'ignore' });\n _claudeAvailable = true;\n } catch {\n _claudeAvailable = false;\n }\n return _claudeAvailable;\n}\n\n/**\n * Returns `true` when mock mode is active.\n *\n * Mock mode is enabled when:\n * - The environment variable `COLESLAW_MOCK=1` is set, OR\n * - The `claude` CLI is not found on PATH.\n */\nexport function isMockMode(): boolean {\n if (process.env['COLESLAW_MOCK'] === '1') return true;\n return !isClaudeAvailable();\n}\n\n// ---------------------------------------------------------------------------\n// Mock implementation\n// ---------------------------------------------------------------------------\n\n/**\n * Returns a mock response that is deterministic based on the prompt content.\n * Used when Claude CLI is unavailable or when COLESLAW_MOCK=1 is set.\n */\nasync function invokeMock(options: InvokeOptions): Promise<InvokeResult> {\n // Tiny delay to simulate async work\n await new Promise((resolve) => setTimeout(resolve, 30 + Math.random() * 70));\n\n const lower = options.prompt.toLowerCase();\n\n let output: string;\n if (lower.includes('opening') || lower.includes('initial position')) {\n output =\n '[Mock] Acknowledged the agenda. From my department perspective, I see several important considerations. ' +\n 'We should ensure proper separation of concerns and define clear boundaries. ' +\n 'Key concern: we must avoid tight coupling between new and existing components.';\n } else if (lower.includes('synthesis') || lower.includes('final position')) {\n output =\n '[Mock] FINAL POSITION: I support the agreed approach. Action items for my department: ' +\n '(1) Deliver the agreed outputs, (2) Coordinate with dependent departments, ' +\n '(3) Report completion status once done.';\n } else if (lower.includes('discussion') || lower.includes('perspective')) {\n output =\n '[Mock] Building on the previous points, I propose we move forward with the discussed approach. ' +\n 'This aligns with existing patterns and allows parallel work across departments. ' +\n 'I can have my team start on the deliverables immediately.';\n } else if (lower.includes('schema') || lower.includes('design')) {\n output =\n '[Mock] Schema analysis complete. Proposed 3 tables with proper foreign-key relationships and indexes. ' +\n 'No circular dependencies detected.';\n } else if (lower.includes('test')) {\n output =\n '[Mock] Test suite generated: 8 unit tests, 2 integration tests. All assertions use strict equality. ' +\n 'Coverage target: 90%.';\n } else if (lower.includes('implement') || lower.includes('build') || lower.includes('feature')) {\n output =\n '[Mock] Implementation complete. Created 2 new files, modified 1 existing file. ' +\n 'All changes follow project conventions.';\n } else if (lower.includes('research') || lower.includes('explore')) {\n output =\n '[Mock] Research complete. Found 5 relevant code references and 2 documentation entries. ' +\n 'Summary provided in structured format.';\n } else if (lower.includes('security') || lower.includes('audit')) {\n output =\n '[Mock] Security audit complete. No critical vulnerabilities found. ' +\n '1 advisory: ensure input validation on user-facing endpoints.';\n } else if (lower.includes('fix') || lower.includes('bug')) {\n output =\n '[Mock] Bug fix applied. Root cause identified and corrected. Fix verified with regression test.';\n } else {\n output = '[Mock] Task completed successfully. Output ready for review.';\n }\n\n return {\n success: true,\n output,\n costUsd: 0,\n };\n}\n\n// ---------------------------------------------------------------------------\n// Real Claude CLI invocation\n// ---------------------------------------------------------------------------\n\n/**\n * Spawn the `claude` CLI as a subprocess and collect its output.\n *\n * The CLI is invoked in non-interactive `--print` mode with JSON output\n * format, a custom system prompt, tool restrictions, and turn limits.\n */\nasync function invokeReal(options: InvokeOptions): Promise<InvokeResult> {\n const {\n prompt,\n systemPrompt,\n allowedTools,\n maxTurns,\n cwd,\n timeoutMs = 300_000,\n } = options;\n\n const args: string[] = [\n '--print',\n '--output-format', 'json',\n '--no-session-persistence',\n ];\n\n if (systemPrompt) {\n args.push('--append-system-prompt', systemPrompt);\n }\n\n if (allowedTools.length > 0) {\n args.push('--allowedTools', allowedTools.join(','));\n }\n\n // Prompt via stdin (avoids ARG_MAX issues with long prompts)\n // Do NOT add prompt as positional arg\n\n logger.info('Invoking Claude CLI', {\n promptLength: prompt.length as unknown as string,\n toolCount: allowedTools.length as unknown as string,\n });\n\n return new Promise<InvokeResult>((resolve) => {\n const child = spawn('claude', args, {\n cwd: cwd ?? process.cwd(),\n stdio: ['pipe', 'pipe', 'pipe'],\n env: { ...process.env },\n });\n\n // Send prompt via stdin\n child.stdin.write(prompt);\n child.stdin.end();\n\n const stdoutChunks: Buffer[] = [];\n const stderrChunks: Buffer[] = [];\n\n child.stdout.on('data', (chunk: Buffer) => {\n stdoutChunks.push(chunk);\n });\n\n child.stderr.on('data', (chunk: Buffer) => {\n stderrChunks.push(chunk);\n });\n\n // Timeout guard\n const timer = setTimeout(() => {\n logger.warn('Claude CLI timed out, killing process', { timeoutMs: timeoutMs as unknown as string });\n child.kill('SIGTERM');\n // Give it a moment to clean up, then force-kill\n setTimeout(() => {\n if (!child.killed) child.kill('SIGKILL');\n }, 5_000);\n }, timeoutMs);\n\n child.on('close', (code) => {\n clearTimeout(timer);\n\n const rawStdout = Buffer.concat(stdoutChunks).toString('utf-8');\n const rawStderr = Buffer.concat(stderrChunks).toString('utf-8');\n\n if (code !== 0) {\n logger.error('Claude CLI exited with non-zero code', {\n exitCode: String(code),\n });\n resolve({\n success: false,\n output: '',\n error: rawStderr || `Claude CLI exited with code ${code}`,\n });\n return;\n }\n\n // Try to parse JSON output from the CLI\n const parsed = parseCliOutput(rawStdout);\n\n logger.info('Claude CLI invocation completed', {\n outputLength: String(parsed.output.length),\n });\n\n resolve(parsed);\n });\n\n child.on('error', (err) => {\n clearTimeout(timer);\n logger.error('Failed to spawn Claude CLI', { error: err.message });\n resolve({\n success: false,\n output: '',\n error: `Failed to spawn Claude CLI: ${err.message}`,\n });\n });\n });\n}\n\n// ---------------------------------------------------------------------------\n// Output parsing\n// ---------------------------------------------------------------------------\n\ninterface CliJsonOutput {\n result?: string;\n output?: string;\n cost_usd?: number;\n is_error?: boolean;\n error?: string;\n}\n\n/**\n * Parse the JSON (or plain-text) output from the Claude CLI.\n *\n * The `--output-format json` flag produces a JSON object. If parsing fails\n * we fall back to treating the raw text as the output.\n */\nfunction parseCliOutput(raw: string): InvokeResult {\n const trimmed = raw.trim();\n if (!trimmed) {\n return { success: false, output: '', error: 'Empty output from Claude CLI' };\n }\n\n try {\n const json = JSON.parse(trimmed) as CliJsonOutput;\n\n if (json.is_error || json.error) {\n return {\n success: false,\n output: json.result ?? json.output ?? '',\n error: json.error ?? 'Unknown CLI error',\n costUsd: json.cost_usd,\n };\n }\n\n return {\n success: true,\n output: json.result ?? json.output ?? trimmed,\n costUsd: json.cost_usd,\n };\n } catch {\n // Not valid JSON — treat as raw text output\n return {\n success: true,\n output: trimmed,\n };\n }\n}\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Invoke Claude to process a prompt.\n *\n * When `COLESLAW_MOCK=1` is set or the `claude` CLI is not available on PATH,\n * this automatically falls back to a mock implementation with a warning log.\n */\nexport async function invokeClaude(options: InvokeOptions): Promise<InvokeResult> {\n if (isMockMode()) {\n if (!isClaudeAvailable()) {\n logger.warn('Claude CLI not found on PATH — using mock mode');\n } else {\n logger.info('COLESLAW_MOCK=1 set — using mock mode');\n }\n return invokeMock(options);\n }\n\n return invokeReal(options);\n}\n\n/**\n * Build InvokeOptions from an AgentConfig, a user prompt, and a system prompt.\n *\n * This is a convenience helper that maps the AgentConfig fields into the\n * shape expected by `invokeClaude`.\n */\nexport function buildInvokeOptions(\n config: AgentConfig,\n prompt: string,\n systemPrompt: string,\n cwd?: string,\n): InvokeOptions {\n return {\n prompt,\n systemPrompt,\n allowedTools: config.allowedTools,\n maxTurns: config.maxTurns,\n cwd,\n };\n}\n","import type {\n AgentNode,\n Department,\n TranscriptEntry,\n MeetingStatus,\n MeetingPhase,\n MinutesRecord,\n ActionItem,\n} from '../types/index.js';\nimport { DEFAULT_MEETING_CONFIG } from '../types/index.js';\nimport {\n getMeeting,\n updateMeeting,\n createMinutes,\n} from '../storage/index.js';\nimport { getDb } from '../storage/db.js';\nimport { getLeaderSystemPrompt } from '../agents/leader-prompts.js';\nimport { createAgentConfig } from '../agents/agent-factory.js';\nimport { invokeClaude, buildInvokeOptions } from '../agents/claude-invoker.js';\nimport { eventBus } from './event-bus.js';\nimport { logger } from '../utils/logger.js';\n\n// ---------------------------------------------------------------------------\n// Agent query — uses Claude CLI or falls back to mock\n// ---------------------------------------------------------------------------\n\ninterface AgentQueryConfig {\n role: string;\n department: Department;\n systemPrompt: string;\n}\n\n/**\n * Query a Claude agent via the CLI subprocess invoker.\n *\n * When COLESLAW_MOCK=1 is set or the `claude` CLI is not available, this\n * automatically falls back to mock responses inside `invokeClaude`.\n */\nasync function queryAgent(config: AgentQueryConfig, prompt: string): Promise<string> {\n const agentConfig = createAgentConfig({\n tier: 'leader',\n role: config.role,\n department: config.department,\n });\n\n const invokeOpts = buildInvokeOptions(\n agentConfig,\n prompt,\n config.systemPrompt,\n );\n\n // Leaders get a 10-minute timeout\n invokeOpts.timeoutMs = 600_000;\n\n const result = await invokeClaude(invokeOpts);\n\n if (!result.success) {\n logger.warn(`Agent query failed for ${config.role}: ${result.error}`);\n // Return the error as content so the meeting can continue\n return `[Error from ${config.role}] ${result.error ?? 'Unknown error during agent invocation'}`;\n }\n\n return result.output;\n}\n\n// ---------------------------------------------------------------------------\n// Transcript helpers (direct DB access since there is no transcript store)\n// ---------------------------------------------------------------------------\n\nfunction insertTranscriptEntry(\n meetingId: string,\n speakerId: string,\n speakerRole: string,\n agendaItemIndex: number,\n roundNumber: number,\n content: string,\n): TranscriptEntry {\n const db = getDb();\n const now = Date.now();\n const tokenCount = Math.ceil(content.length / 4); // rough approximation\n\n const result = db\n .prepare(\n `INSERT INTO transcript_entries\n (meeting_id, speaker_id, speaker_role, agenda_item_index, round_number, content, token_count, created_at)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?)`,\n )\n .run(meetingId, speakerId, speakerRole, agendaItemIndex, roundNumber, content, tokenCount, now);\n\n return {\n id: Number(result.lastInsertRowid),\n meetingId,\n speakerId,\n speakerRole,\n agendaItemIndex,\n roundNumber,\n content,\n tokenCount,\n createdAt: now,\n };\n}\n\nfunction getTranscript(meetingId: string): TranscriptEntry[] {\n const db = getDb();\n interface TranscriptRow {\n id: number;\n meeting_id: string;\n speaker_id: string;\n speaker_role: string;\n agenda_item_index: number;\n round_number: number;\n content: string;\n token_count: number;\n created_at: number;\n }\n const rows = db\n .prepare('SELECT * FROM transcript_entries WHERE meeting_id = ? ORDER BY created_at ASC')\n .all(meetingId) as TranscriptRow[];\n\n return rows.map((r) => ({\n id: r.id,\n meetingId: r.meeting_id,\n speakerId: r.speaker_id,\n speakerRole: r.speaker_role,\n agendaItemIndex: r.agenda_item_index,\n roundNumber: r.round_number,\n content: r.content,\n tokenCount: r.token_count,\n createdAt: r.created_at,\n }));\n}\n\n// ---------------------------------------------------------------------------\n// MeetingRunner\n// ---------------------------------------------------------------------------\n\nexport class MeetingRunner {\n private readonly meetingId: string;\n private readonly leaders: AgentNode[];\n private readonly maxRoundsPerItem: number;\n private readonly projectContext: string | undefined;\n\n constructor(meetingId: string, leaders: AgentNode[], projectContext?: string) {\n this.meetingId = meetingId;\n this.leaders = leaders;\n this.maxRoundsPerItem = DEFAULT_MEETING_CONFIG.maxRoundsPerItem;\n this.projectContext = projectContext;\n }\n\n // ---- public entry point -------------------------------------------------\n\n /**\n * Run the complete meeting lifecycle: opening -> discussion -> synthesis -> minutes.\n */\n async run(): Promise<void> {\n const meeting = getMeeting(this.meetingId);\n if (!meeting) {\n throw new Error(`Meeting not found: ${this.meetingId}`);\n }\n\n logger.info(`Starting meeting: ${meeting.topic}`, { meetingId: this.meetingId });\n\n try {\n await this.openingPhase();\n await this.discussionPhase();\n await this.synthesisPhase();\n await this.generateMinutes();\n\n updateMeeting(this.meetingId, {\n status: 'completed' as MeetingStatus,\n completedAt: Date.now(),\n });\n\n logger.info(`Meeting completed: ${meeting.topic}`, { meetingId: this.meetingId });\n } catch (err) {\n const errorMsg = err instanceof Error ? err.message : String(err);\n logger.error(`Meeting failed: ${errorMsg}`, { meetingId: this.meetingId });\n\n updateMeeting(this.meetingId, {\n status: 'failed' as MeetingStatus,\n completedAt: Date.now(),\n });\n\n throw err;\n }\n }\n\n // ---- phases -------------------------------------------------------------\n\n /**\n * Opening phase: each leader states their initial position on the meeting\n * topic and agenda.\n */\n private async openingPhase(): Promise<void> {\n this.setPhase('opening');\n\n const meeting = getMeeting(this.meetingId)!;\n const agendaText = meeting.agenda.map((a, i) => ` ${i + 1}. ${a}`).join('\\n');\n\n for (const leader of this.leaders) {\n const prompt =\n `MEETING OPENING\\n\\n` +\n `Topic: ${meeting.topic}\\n` +\n `Agenda:\\n${agendaText}\\n\\n` +\n `Please state your initial position on this topic from your department's perspective. ` +\n `Identify any concerns, dependencies, or risks relevant to your area.`;\n\n const config: AgentQueryConfig = {\n role: leader.role,\n department: leader.department,\n systemPrompt: getLeaderSystemPrompt(leader.department, undefined, this.projectContext),\n };\n\n const response = await queryAgent(config, prompt);\n\n insertTranscriptEntry(\n this.meetingId,\n leader.id,\n leader.role,\n -1, // -1 signals the opening phase (not tied to a specific agenda item)\n 0,\n response,\n );\n\n eventBus.emitAgentEvent({\n kind: 'message_sent',\n fromId: leader.id,\n toId: 'meeting',\n summary: `[Opening] ${leader.role}: ${response.slice(0, 80)}...`,\n });\n\n logger.debug(`Opening statement from ${leader.role}`, {\n meetingId: this.meetingId,\n agentId: leader.id,\n });\n }\n }\n\n /**\n * Discussion phase: for each agenda item, leaders take turns responding in\n * round-robin fashion for up to `maxRoundsPerItem` rounds.\n */\n private async discussionPhase(): Promise<void> {\n this.setPhase('discussion');\n\n const meeting = getMeeting(this.meetingId)!;\n\n for (let itemIdx = 0; itemIdx < meeting.agenda.length; itemIdx++) {\n const agendaItem = meeting.agenda[itemIdx];\n\n logger.info(`Discussing agenda item ${itemIdx + 1}: ${agendaItem}`, {\n meetingId: this.meetingId,\n });\n\n for (let round = 1; round <= this.maxRoundsPerItem; round++) {\n for (const leader of this.leaders) {\n // Build the prompt with full transcript context\n const transcript = getTranscript(this.meetingId);\n const transcriptText = this.formatTranscript(transcript);\n\n const prompt =\n `MEETING DISCUSSION — Round ${round}/${this.maxRoundsPerItem}\\n\\n` +\n `Current agenda item (${itemIdx + 1}/${meeting.agenda.length}): ${agendaItem}\\n\\n` +\n `Transcript so far:\\n${transcriptText}\\n\\n` +\n `Provide your department's perspective on this agenda item. ` +\n `Build on what others have said. If you agree, say so and add specifics. ` +\n `If you disagree, state your reasoning and propose an alternative.`;\n\n const config: AgentQueryConfig = {\n role: leader.role,\n department: leader.department,\n systemPrompt: getLeaderSystemPrompt(leader.department, undefined, this.projectContext),\n };\n\n const response = await queryAgent(config, prompt);\n\n insertTranscriptEntry(\n this.meetingId,\n leader.id,\n leader.role,\n itemIdx,\n round,\n response,\n );\n\n eventBus.emitAgentEvent({\n kind: 'message_sent',\n fromId: leader.id,\n toId: 'meeting',\n summary: `[Item ${itemIdx + 1}, R${round}] ${leader.role}: ${response.slice(0, 80)}...`,\n });\n }\n }\n }\n }\n\n /**\n * Synthesis phase: each leader states their final position, commitments,\n * and action items.\n */\n private async synthesisPhase(): Promise<void> {\n this.setPhase('synthesis');\n\n const transcript = getTranscript(this.meetingId);\n const transcriptText = this.formatTranscript(transcript);\n\n for (const leader of this.leaders) {\n const prompt =\n `MEETING SYNTHESIS\\n\\n` +\n `The discussion is complete. Here is the full transcript:\\n${transcriptText}\\n\\n` +\n `State your final position. List the action items your department commits to. ` +\n `Flag any unresolved concerns or items requiring user decision.`;\n\n const config: AgentQueryConfig = {\n role: leader.role,\n department: leader.department,\n systemPrompt: getLeaderSystemPrompt(leader.department, undefined, this.projectContext),\n };\n\n const response = await queryAgent(config, prompt);\n\n insertTranscriptEntry(\n this.meetingId,\n leader.id,\n leader.role,\n -2, // -2 signals synthesis phase\n 0,\n response,\n );\n\n eventBus.emitAgentEvent({\n kind: 'message_sent',\n fromId: leader.id,\n toId: 'meeting',\n summary: `[Synthesis] ${leader.role}: ${response.slice(0, 80)}...`,\n });\n }\n }\n\n /**\n * Generate meeting minutes by concatenating and formatting the transcript.\n *\n * In the future this will use a dedicated minutes-writer agent. For now it\n * formats the transcript into a structured summary.\n */\n private async generateMinutes(): Promise<void> {\n this.setPhase('minutes-generation');\n\n const meeting = getMeeting(this.meetingId)!;\n const transcript = getTranscript(this.meetingId);\n\n // --- Build the minutes content ---\n\n const sections: string[] = [];\n\n sections.push(`# Meeting Minutes`);\n sections.push(`## Topic: ${meeting.topic}`);\n sections.push(`## Date: ${new Date().toISOString()}`);\n sections.push(`## Participants: ${this.leaders.map((l) => l.role).join(', ')}`);\n sections.push('');\n\n // Agenda\n sections.push(`## Agenda`);\n meeting.agenda.forEach((item, i) => {\n sections.push(`${i + 1}. ${item}`);\n });\n sections.push('');\n\n // Opening statements\n const openingEntries = transcript.filter((e) => e.agendaItemIndex === -1);\n if (openingEntries.length > 0) {\n sections.push(`## Opening Statements`);\n for (const entry of openingEntries) {\n sections.push(`### ${entry.speakerRole}`);\n sections.push(entry.content);\n sections.push('');\n }\n }\n\n // Discussion per agenda item\n for (let i = 0; i < meeting.agenda.length; i++) {\n const itemEntries = transcript.filter((e) => e.agendaItemIndex === i);\n if (itemEntries.length > 0) {\n sections.push(`## Discussion: ${meeting.agenda[i]}`);\n for (const entry of itemEntries) {\n sections.push(`**${entry.speakerRole}** (round ${entry.roundNumber}):`);\n sections.push(entry.content);\n sections.push('');\n }\n }\n }\n\n // Synthesis\n const synthesisEntries = transcript.filter((e) => e.agendaItemIndex === -2);\n if (synthesisEntries.length > 0) {\n sections.push(`## Final Positions`);\n for (const entry of synthesisEntries) {\n sections.push(`### ${entry.speakerRole}`);\n sections.push(entry.content);\n sections.push('');\n }\n }\n\n const content = sections.join('\\n');\n\n // --- Extract action items from synthesis entries ---\n\n const actionItems: ActionItem[] = this.leaders.map((leader, idx) => ({\n id: `action-${this.meetingId}-${idx}`,\n title: `${leader.role} deliverables`,\n description: `Action items committed by ${leader.role} during synthesis phase`,\n assignedDepartment: leader.department,\n assignedRole: leader.role,\n priority: 'medium' as const,\n dependencies: [],\n acceptanceCriteria: ['Deliverables completed as stated in final position'],\n }));\n\n createMinutes({\n meetingId: this.meetingId,\n format: 'summary',\n content,\n actionItems,\n });\n\n logger.info('Minutes generated', { meetingId: this.meetingId });\n }\n\n // ---- helpers ------------------------------------------------------------\n\n private setPhase(phase: MeetingPhase): void {\n const statusMap: Record<MeetingPhase, MeetingStatus> = {\n 'orchestrator-phase': 'pending',\n 'convening': 'convening',\n 'opening': 'opening',\n 'discussion': 'discussion',\n 'research-break': 'discussion',\n 'synthesis': 'synthesis',\n 'minutes-generation': 'minutes-generation',\n };\n\n updateMeeting(this.meetingId, {\n phase,\n status: statusMap[phase] ?? 'discussion',\n });\n\n logger.debug(`Meeting phase: ${phase}`, { meetingId: this.meetingId });\n }\n\n private formatTranscript(entries: TranscriptEntry[]): string {\n if (entries.length === 0) return '(No transcript entries yet)';\n\n return entries\n .map((e) => {\n let phaseLabel: string;\n if (e.agendaItemIndex === -1) phaseLabel = 'Opening';\n else if (e.agendaItemIndex === -2) phaseLabel = 'Synthesis';\n else phaseLabel = `Item ${e.agendaItemIndex + 1}, Round ${e.roundNumber}`;\n return `[${phaseLabel}] ${e.speakerRole}: ${e.content}`;\n })\n .join('\\n\\n');\n }\n}\n","import { existsSync, readFileSync, readdirSync, statSync } from 'node:fs';\nimport { join, basename, extname } from 'node:path';\nimport { logger } from '../utils/logger.js';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport type ProjectLanguage =\n | 'javascript'\n | 'typescript'\n | 'python'\n | 'java'\n | 'kotlin'\n | 'go'\n | 'rust'\n | 'swift'\n | 'dart'\n | 'ruby'\n | 'csharp'\n | 'cpp'\n | 'unknown';\n\n/** Language-agnostic dependency info extracted from any manifest file. */\nexport interface DependencyManifest {\n file: string; // e.g. \"package.json\", \"build.gradle.kts\"\n language: ProjectLanguage;\n dependencies: Record<string, string>; // name -> version/spec\n devDependencies: Record<string, string>;\n scripts: Record<string, string>; // build/test/run commands\n metadata: Record<string, string>; // language-specific extras\n}\n\nexport interface ProjectAnalysis {\n /** Primary language detected. */\n language: ProjectLanguage;\n\n /** All dependency manifests found (can be multi-language monorepo). */\n manifests: DependencyManifest[];\n\n /** Parsed package.json contents, or null if not found. (Kept for backward compat.) */\n packageJson: {\n name: string;\n dependencies: Record<string, string>;\n devDependencies: Record<string, string>;\n scripts: Record<string, string>;\n type?: string; // \"module\" or \"commonjs\"\n } | null;\n\n /** High-level project structure signals. */\n structure: {\n hasTypescript: boolean;\n hasSrcDir: boolean;\n hasTestDir: boolean;\n configFiles: string[]; // tsconfig, eslint, prettier, etc.\n entryPoints: string[];\n };\n\n /** Detected coding patterns and tooling. */\n patterns: {\n importStyle: 'esm' | 'commonjs' | 'mixed';\n testFramework: string | null; // vitest, jest, mocha, etc.\n linter: string | null; // eslint, biome, etc.\n formatter: string | null; // prettier, biome, etc.\n buildTool: string | null; // tsup, esbuild, webpack, vite, etc.\n };\n\n /** Existing utility files and their named exports. */\n existingUtils: {\n file: string;\n exports: string[];\n }[];\n}\n\n// ---------------------------------------------------------------------------\n// Config-file detection lists\n// ---------------------------------------------------------------------------\n\nconst CONFIG_FILE_PATTERNS: string[] = [\n 'tsconfig.json',\n 'tsconfig.build.json',\n 'tsconfig.node.json',\n '.eslintrc',\n '.eslintrc.js',\n '.eslintrc.cjs',\n '.eslintrc.json',\n '.eslintrc.yml',\n '.eslintrc.yaml',\n 'eslint.config.js',\n 'eslint.config.mjs',\n 'eslint.config.cjs',\n 'eslint.config.ts',\n '.prettierrc',\n '.prettierrc.js',\n '.prettierrc.cjs',\n '.prettierrc.json',\n '.prettierrc.yml',\n '.prettierrc.yaml',\n 'prettier.config.js',\n 'prettier.config.mjs',\n 'prettier.config.cjs',\n 'biome.json',\n 'biome.jsonc',\n 'vite.config.ts',\n 'vite.config.js',\n 'vite.config.mjs',\n 'webpack.config.js',\n 'webpack.config.ts',\n 'webpack.config.mjs',\n 'rollup.config.js',\n 'rollup.config.ts',\n 'rollup.config.mjs',\n 'tsup.config.ts',\n 'tsup.config.js',\n 'esbuild.config.js',\n 'esbuild.config.ts',\n 'jest.config.js',\n 'jest.config.ts',\n 'jest.config.mjs',\n 'vitest.config.ts',\n 'vitest.config.js',\n 'vitest.config.mts',\n '.mocharc.yml',\n '.mocharc.json',\n '.mocharc.js',\n '.babelrc',\n 'babel.config.js',\n 'babel.config.json',\n '.swcrc',\n 'turbo.json',\n 'nx.json',\n];\n\n/** Directories that commonly house reusable utility code. */\nconst UTIL_DIR_NAMES = ['utils', 'lib', 'helpers', 'shared', 'common'];\n\n/** Language-specific dependency manifest files and how to parse them. */\nconst MANIFEST_FILES: {\n file: string;\n language: ProjectLanguage;\n parse: (content: string, projectDir: string) => Omit<DependencyManifest, 'file' | 'language'>;\n}[] = [\n // -- JavaScript / TypeScript --\n {\n file: 'package.json',\n language: 'typescript', // refined later if no TS config\n parse: (content) => {\n const raw = JSON.parse(content);\n return {\n dependencies: raw.dependencies ?? {},\n devDependencies: raw.devDependencies ?? {},\n scripts: raw.scripts ?? {},\n metadata: { type: raw.type ?? 'commonjs', name: raw.name ?? '' },\n };\n },\n },\n // -- Python --\n {\n file: 'pyproject.toml',\n language: 'python',\n parse: (content) => {\n const deps: Record<string, string> = {};\n const devDeps: Record<string, string> = {};\n const scripts: Record<string, string> = {};\n // Parse [project.dependencies]\n for (const m of content.matchAll(/^\\s*\"([^\"]+?)(?:[><=!~]+.*)?\".*$/gm)) {\n deps[m[1]] = '*';\n }\n // Parse [project.scripts]\n for (const m of content.matchAll(/^(\\w[\\w-]*)\\s*=\\s*\"([^\"]+)\"/gm)) {\n scripts[m[1]] = m[2];\n }\n return { dependencies: deps, devDependencies: devDeps, scripts, metadata: {} };\n },\n },\n {\n file: 'requirements.txt',\n language: 'python',\n parse: (content) => {\n const deps: Record<string, string> = {};\n for (const line of content.split('\\n')) {\n const trimmed = line.trim();\n if (!trimmed || trimmed.startsWith('#') || trimmed.startsWith('-')) continue;\n const match = trimmed.match(/^([a-zA-Z0-9_-]+)\\s*([><=!~].*)?$/);\n if (match) deps[match[1]] = match[2]?.trim() ?? '*';\n }\n return { dependencies: deps, devDependencies: {}, scripts: {}, metadata: {} };\n },\n },\n {\n file: 'Pipfile',\n language: 'python',\n parse: (content) => {\n const deps: Record<string, string> = {};\n const inPackages = content.indexOf('[packages]');\n if (inPackages >= 0) {\n const section = content.slice(inPackages);\n for (const m of section.matchAll(/^(\\w[\\w-]*)\\s*=\\s*\"([^\"]+)\"/gm)) {\n deps[m[1]] = m[2];\n }\n }\n return { dependencies: deps, devDependencies: {}, scripts: {}, metadata: {} };\n },\n },\n // -- Java / Kotlin (Gradle) --\n {\n file: 'build.gradle',\n language: 'java',\n parse: (content) => {\n const deps: Record<string, string> = {};\n // implementation 'group:artifact:version'\n for (const m of content.matchAll(/(?:implementation|api|compileOnly)\\s+['\"]([^'\"]+)['\"]/g)) {\n const parts = m[1].split(':');\n if (parts.length >= 2) deps[`${parts[0]}:${parts[1]}`] = parts[2] ?? '*';\n }\n return { dependencies: deps, devDependencies: {}, scripts: {}, metadata: { buildSystem: 'gradle' } };\n },\n },\n {\n file: 'build.gradle.kts',\n language: 'kotlin',\n parse: (content) => {\n const deps: Record<string, string> = {};\n for (const m of content.matchAll(/(?:implementation|api|compileOnly)\\s*\\(\\s*\"([^\"]+)\"\\s*\\)/g)) {\n const parts = m[1].split(':');\n if (parts.length >= 2) deps[`${parts[0]}:${parts[1]}`] = parts[2] ?? '*';\n }\n return { dependencies: deps, devDependencies: {}, scripts: {}, metadata: { buildSystem: 'gradle-kts' } };\n },\n },\n {\n file: 'pom.xml',\n language: 'java',\n parse: (content) => {\n const deps: Record<string, string> = {};\n for (const m of content.matchAll(/<dependency>\\s*<groupId>([^<]+)<\\/groupId>\\s*<artifactId>([^<]+)<\\/artifactId>(?:\\s*<version>([^<]+)<\\/version>)?/gs)) {\n deps[`${m[1]}:${m[2]}`] = m[3] ?? '*';\n }\n return { dependencies: deps, devDependencies: {}, scripts: {}, metadata: { buildSystem: 'maven' } };\n },\n },\n // -- Go --\n {\n file: 'go.mod',\n language: 'go',\n parse: (content) => {\n const deps: Record<string, string> = {};\n for (const m of content.matchAll(/^\\s+(\\S+)\\s+(v[\\d.]+\\S*)/gm)) {\n deps[m[1]] = m[2];\n }\n const moduleMatch = content.match(/^module\\s+(\\S+)/m);\n return { dependencies: deps, devDependencies: {}, scripts: {}, metadata: { module: moduleMatch?.[1] ?? '' } };\n },\n },\n // -- Rust --\n {\n file: 'Cargo.toml',\n language: 'rust',\n parse: (content) => {\n const deps: Record<string, string> = {};\n const devDeps: Record<string, string> = {};\n let inDeps = false;\n let inDevDeps = false;\n for (const line of content.split('\\n')) {\n if (line.match(/^\\[dependencies\\]/)) { inDeps = true; inDevDeps = false; continue; }\n if (line.match(/^\\[dev-dependencies\\]/)) { inDevDeps = true; inDeps = false; continue; }\n if (line.match(/^\\[/)) { inDeps = false; inDevDeps = false; continue; }\n const m = line.match(/^(\\w[\\w-]*)\\s*=\\s*\"([^\"]+)\"/);\n if (m) {\n if (inDeps) deps[m[1]] = m[2];\n if (inDevDeps) devDeps[m[1]] = m[2];\n }\n }\n return { dependencies: deps, devDependencies: devDeps, scripts: {}, metadata: {} };\n },\n },\n // -- Swift --\n {\n file: 'Package.swift',\n language: 'swift',\n parse: (content) => {\n const deps: Record<string, string> = {};\n for (const m of content.matchAll(/\\.package\\s*\\(\\s*url:\\s*\"([^\"]+)\"/g)) {\n const name = m[1].split('/').pop()?.replace('.git', '') ?? m[1];\n deps[name] = '*';\n }\n return { dependencies: deps, devDependencies: {}, scripts: {}, metadata: {} };\n },\n },\n // -- Dart / Flutter --\n {\n file: 'pubspec.yaml',\n language: 'dart',\n parse: (content) => {\n const deps: Record<string, string> = {};\n let inDeps = false;\n for (const line of content.split('\\n')) {\n if (line.match(/^dependencies:/)) { inDeps = true; continue; }\n if (line.match(/^\\S/) && inDeps) { inDeps = false; continue; }\n if (inDeps) {\n const m = line.match(/^\\s+(\\w[\\w_-]*):\\s*(.+)?/);\n if (m) deps[m[1]] = m[2]?.trim() ?? '*';\n }\n }\n return { dependencies: deps, devDependencies: {}, scripts: {}, metadata: {} };\n },\n },\n // -- Ruby --\n {\n file: 'Gemfile',\n language: 'ruby',\n parse: (content) => {\n const deps: Record<string, string> = {};\n for (const m of content.matchAll(/gem\\s+['\"]([^'\"]+)['\"]/g)) {\n deps[m[1]] = '*';\n }\n return { dependencies: deps, devDependencies: {}, scripts: {}, metadata: {} };\n },\n },\n // -- C# / .NET --\n {\n file: '*.csproj', // handled specially in the scanner\n language: 'csharp',\n parse: (content) => {\n const deps: Record<string, string> = {};\n for (const m of content.matchAll(/<PackageReference\\s+Include=\"([^\"]+)\"\\s+Version=\"([^\"]+)\"/g)) {\n deps[m[1]] = m[2];\n }\n return { dependencies: deps, devDependencies: {}, scripts: {}, metadata: { buildSystem: 'dotnet' } };\n },\n },\n];\n\n/** Detect project language from found manifests. */\nfunction detectLanguage(projectDir: string, manifests: DependencyManifest[]): ProjectLanguage {\n if (manifests.length === 0) return 'unknown';\n\n // If there's a tsconfig, it's TypeScript regardless\n if (existsSync(join(projectDir, 'tsconfig.json'))) return 'typescript';\n\n // Use the first manifest's language as primary\n const languages = manifests.map((m) => m.language);\n if (languages.includes('typescript')) return 'typescript';\n if (languages.includes('kotlin')) return 'kotlin';\n\n return languages[0];\n}\n\n/** Scan for all dependency manifests in a project. */\nfunction scanManifests(projectDir: string): DependencyManifest[] {\n const results: DependencyManifest[] = [];\n\n for (const spec of MANIFEST_FILES) {\n // Handle glob pattern (*.csproj)\n if (spec.file.includes('*')) {\n const ext = spec.file.replace('*', '');\n try {\n const entries = readdirSync(projectDir);\n for (const entry of entries) {\n if (entry.endsWith(ext)) {\n const content = readFileSync(join(projectDir, entry), 'utf-8');\n try {\n const parsed = spec.parse(content, projectDir);\n results.push({ file: entry, language: spec.language, ...parsed });\n } catch { /* skip malformed */ }\n }\n }\n } catch { /* skip */ }\n continue;\n }\n\n const filePath = join(projectDir, spec.file);\n if (!existsSync(filePath)) continue;\n\n try {\n const content = readFileSync(filePath, 'utf-8');\n const parsed = spec.parse(content, projectDir);\n results.push({ file: spec.file, language: spec.language, ...parsed });\n } catch {\n logger.debug(`Failed to parse manifest: ${spec.file}`);\n }\n }\n\n return results;\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction readJsonSafe(filePath: string): unknown | null {\n try {\n const raw = readFileSync(filePath, 'utf-8');\n return JSON.parse(raw);\n } catch {\n return null;\n }\n}\n\n/** Collect named exports from a .ts or .js file using lightweight regex. */\nfunction extractExports(filePath: string): string[] {\n try {\n const content = readFileSync(filePath, 'utf-8');\n const exports: string[] = [];\n\n // export function foo\n for (const m of content.matchAll(/export\\s+(?:async\\s+)?function\\s+(\\w+)/g)) {\n exports.push(m[1]);\n }\n // export class Foo\n for (const m of content.matchAll(/export\\s+class\\s+(\\w+)/g)) {\n exports.push(m[1]);\n }\n // export const/let/var foo\n for (const m of content.matchAll(/export\\s+(?:const|let|var)\\s+(\\w+)/g)) {\n exports.push(m[1]);\n }\n // export interface Foo / export type Foo\n for (const m of content.matchAll(/export\\s+(?:interface|type)\\s+(\\w+)/g)) {\n exports.push(m[1]);\n }\n // export enum Foo\n for (const m of content.matchAll(/export\\s+enum\\s+(\\w+)/g)) {\n exports.push(m[1]);\n }\n // export default (just record \"default\")\n if (/export\\s+default\\s/.test(content)) {\n exports.push('default');\n }\n\n return [...new Set(exports)];\n } catch {\n return [];\n }\n}\n\n/** Sample up to N .ts/.js files from a directory tree (non-recursive beyond 2 levels). */\nfunction sampleSourceFiles(dir: string, max: number): string[] {\n const results: string[] = [];\n const extensions = new Set(['.ts', '.js', '.mts', '.mjs', '.cts', '.cjs']);\n\n function walk(currentDir: string, depth: number): void {\n if (depth > 2 || results.length >= max) return;\n let entries: string[];\n try {\n entries = readdirSync(currentDir);\n } catch {\n return;\n }\n for (const entry of entries) {\n if (results.length >= max) return;\n if (entry.startsWith('.') || entry === 'node_modules' || entry === 'dist') continue;\n const full = join(currentDir, entry);\n try {\n const stat = statSync(full);\n if (stat.isDirectory()) {\n walk(full, depth + 1);\n } else if (stat.isFile() && extensions.has(extname(entry))) {\n results.push(full);\n }\n } catch {\n // Skip inaccessible entries\n }\n }\n }\n\n walk(dir, 0);\n return results;\n}\n\n/** Detect import style by scanning a few source files. */\nfunction detectImportStyle(\n projectDir: string,\n packageType: string | undefined,\n): 'esm' | 'commonjs' | 'mixed' {\n const sourceDir = existsSync(join(projectDir, 'src'))\n ? join(projectDir, 'src')\n : projectDir;\n\n const files = sampleSourceFiles(sourceDir, 10);\n let esmCount = 0;\n let cjsCount = 0;\n\n for (const file of files) {\n try {\n const content = readFileSync(file, 'utf-8');\n if (/\\bimport\\s+/.test(content) || /\\bexport\\s+/.test(content)) {\n esmCount++;\n }\n if (/\\brequire\\s*\\(/.test(content) || /\\bmodule\\.exports\\b/.test(content)) {\n cjsCount++;\n }\n } catch {\n // skip\n }\n }\n\n // If we have no signal from files, fall back to package.json \"type\"\n if (esmCount === 0 && cjsCount === 0) {\n return packageType === 'module' ? 'esm' : 'commonjs';\n }\n\n if (esmCount > 0 && cjsCount > 0) return 'mixed';\n if (esmCount > 0) return 'esm';\n return 'commonjs';\n}\n\nfunction detectTestFramework(deps: Record<string, string>): string | null {\n const candidates: [string, string][] = [\n ['vitest', 'vitest'],\n ['jest', 'jest'],\n ['@jest/core', 'jest'],\n ['mocha', 'mocha'],\n ['ava', 'ava'],\n ['tap', 'tap'],\n ['uvu', 'uvu'],\n ];\n for (const [pkg, name] of candidates) {\n if (pkg in deps) return name;\n }\n return null;\n}\n\nfunction detectLinter(deps: Record<string, string>, configFiles: string[]): string | null {\n if ('biome' in deps || '@biomejs/biome' in deps || configFiles.some((f) => f.startsWith('biome.'))) {\n return 'biome';\n }\n if ('eslint' in deps || configFiles.some((f) => f.includes('eslint'))) {\n return 'eslint';\n }\n return null;\n}\n\nfunction detectFormatter(deps: Record<string, string>, configFiles: string[]): string | null {\n // Biome also formats — if it is the linter and prettier is absent, biome is the formatter\n if ('prettier' in deps || configFiles.some((f) => f.includes('prettier'))) {\n return 'prettier';\n }\n if ('biome' in deps || '@biomejs/biome' in deps || configFiles.some((f) => f.startsWith('biome.'))) {\n return 'biome';\n }\n return null;\n}\n\nfunction detectBuildTool(\n deps: Record<string, string>,\n scripts: Record<string, string>,\n): string | null {\n const candidates: [string, string][] = [\n ['tsup', 'tsup'],\n ['esbuild', 'esbuild'],\n ['vite', 'vite'],\n ['webpack', 'webpack'],\n ['rollup', 'rollup'],\n ['@swc/core', 'swc'],\n ['turbopack', 'turbopack'],\n ['parcel', 'parcel'],\n ];\n\n for (const [pkg, name] of candidates) {\n if (pkg in deps) return name;\n }\n\n // Fallback: check build script content\n const buildScript = scripts['build'] ?? '';\n for (const [, name] of candidates) {\n if (buildScript.includes(name)) return name;\n }\n\n // tsc-only builds\n if (buildScript.includes('tsc')) return 'tsc';\n\n return null;\n}\n\nfunction detectEntryPoints(\n projectDir: string,\n packageJson: ProjectAnalysis['packageJson'],\n): string[] {\n const entries: string[] = [];\n\n if (packageJson) {\n // \"main\" field\n const raw = readJsonSafe(join(projectDir, 'package.json')) as Record<string, unknown> | null;\n if (raw) {\n if (typeof raw['main'] === 'string') entries.push(raw['main']);\n if (typeof raw['module'] === 'string') entries.push(raw['module']);\n if (raw['exports'] && typeof raw['exports'] === 'object') {\n const exp = raw['exports'] as Record<string, unknown>;\n // Check \".\" entry\n const dot = exp['.'];\n if (typeof dot === 'string') {\n entries.push(dot);\n } else if (dot && typeof dot === 'object') {\n const dotObj = dot as Record<string, unknown>;\n if (typeof dotObj['import'] === 'string') entries.push(dotObj['import']);\n if (typeof dotObj['require'] === 'string') entries.push(dotObj['require']);\n }\n }\n }\n }\n\n // Common default entry points\n const commonEntries = ['src/index.ts', 'src/main.ts', 'src/index.js', 'src/main.js', 'index.ts', 'index.js'];\n for (const candidate of commonEntries) {\n if (existsSync(join(projectDir, candidate)) && !entries.includes(candidate)) {\n entries.push(candidate);\n }\n }\n\n return [...new Set(entries)];\n}\n\n/** Collect utility files from well-known directories under src/. */\nfunction collectUtilFiles(projectDir: string): ProjectAnalysis['existingUtils'] {\n const results: ProjectAnalysis['existingUtils'] = [];\n const srcDir = join(projectDir, 'src');\n const extensions = new Set(['.ts', '.js', '.mts', '.mjs']);\n\n for (const dirName of UTIL_DIR_NAMES) {\n const utilDir = join(srcDir, dirName);\n if (!existsSync(utilDir)) continue;\n\n let entries: string[];\n try {\n entries = readdirSync(utilDir);\n } catch {\n continue;\n }\n\n for (const entry of entries) {\n const ext = extname(entry);\n if (!extensions.has(ext)) continue;\n // Skip index files — they are typically re-exports\n if (basename(entry, ext) === 'index') continue;\n\n const filePath = join(utilDir, entry);\n try {\n if (!statSync(filePath).isFile()) continue;\n } catch {\n continue;\n }\n\n const exports = extractExports(filePath);\n if (exports.length > 0) {\n // Store a relative path from projectDir for readability\n const relPath = filePath.slice(projectDir.length + 1);\n results.push({ file: relPath, exports });\n }\n }\n }\n\n return results;\n}\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Analyse a project directory and return structured metadata about its\n * dependencies, tooling, patterns, and existing utilities.\n *\n * This is intentionally lightweight (no AST parsing, limited FS traversal)\n * so it can run before every meeting without noticeable delay.\n */\nexport async function analyzeProject(projectDir: string): Promise<ProjectAnalysis> {\n logger.debug(`Analyzing project: ${projectDir}`);\n\n // 1. Read package.json\n let packageJson: ProjectAnalysis['packageJson'] = null;\n const pkgPath = join(projectDir, 'package.json');\n if (existsSync(pkgPath)) {\n const raw = readJsonSafe(pkgPath) as Record<string, unknown> | null;\n if (raw) {\n packageJson = {\n name: (raw['name'] as string) ?? '',\n dependencies: (raw['dependencies'] as Record<string, string>) ?? {},\n devDependencies: (raw['devDependencies'] as Record<string, string>) ?? {},\n scripts: (raw['scripts'] as Record<string, string>) ?? {},\n type: raw['type'] as string | undefined,\n };\n }\n }\n\n // 2. Detect config files\n const configFiles: string[] = [];\n for (const pattern of CONFIG_FILE_PATTERNS) {\n if (existsSync(join(projectDir, pattern))) {\n configFiles.push(pattern);\n }\n }\n\n // 3. Structure\n const hasTypescript =\n existsSync(join(projectDir, 'tsconfig.json')) ||\n configFiles.some((f) => f.startsWith('tsconfig'));\n const hasSrcDir = existsSync(join(projectDir, 'src'));\n const hasTestDir =\n existsSync(join(projectDir, 'test')) ||\n existsSync(join(projectDir, 'tests')) ||\n existsSync(join(projectDir, '__tests__'));\n const entryPoints = detectEntryPoints(projectDir, packageJson);\n\n const structure: ProjectAnalysis['structure'] = {\n hasTypescript,\n hasSrcDir,\n hasTestDir,\n configFiles,\n entryPoints,\n };\n\n // 4. All deps combined for detection\n const allDeps: Record<string, string> = {\n ...(packageJson?.dependencies ?? {}),\n ...(packageJson?.devDependencies ?? {}),\n };\n\n // 5. Patterns\n const patterns: ProjectAnalysis['patterns'] = {\n importStyle: detectImportStyle(projectDir, packageJson?.type),\n testFramework: detectTestFramework(allDeps),\n linter: detectLinter(allDeps, configFiles),\n formatter: detectFormatter(allDeps, configFiles),\n buildTool: detectBuildTool(allDeps, packageJson?.scripts ?? {}),\n };\n\n // 6. Existing utility files\n const existingUtils = collectUtilFiles(projectDir);\n\n // 7. Scan all language-specific manifests\n const manifests = scanManifests(projectDir);\n\n // 8. Detect primary language\n const language = detectLanguage(projectDir, manifests);\n\n logger.debug(`Project analysis complete: ${packageJson?.name ?? '(unnamed)'}, language: ${language}, manifests: ${manifests.length}`, {\n department: 'research',\n });\n\n return {\n language,\n manifests,\n packageJson,\n structure,\n patterns,\n existingUtils,\n };\n}\n\n/**\n * Format a {@link ProjectAnalysis} into a Markdown summary suitable for\n * injection into agent system prompts.\n */\nexport function formatProjectContext(analysis: ProjectAnalysis): string {\n const sections: string[] = [];\n\n // Header\n sections.push('## Project Context');\n sections.push('');\n sections.push(`**Primary Language:** ${analysis.language}`);\n sections.push('');\n\n // Multi-language manifests (non-JS)\n const nonJsManifests = analysis.manifests.filter((m) => m.file !== 'package.json');\n if (nonJsManifests.length > 0) {\n sections.push('### Dependency Manifests');\n for (const manifest of nonJsManifests) {\n sections.push(`#### ${manifest.file} (${manifest.language})`);\n const depNames = Object.keys(manifest.dependencies);\n if (depNames.length > 0) {\n sections.push(depNames.slice(0, 30).map((d) => `- \\`${d}\\`: ${manifest.dependencies[d]}`).join('\\n'));\n if (depNames.length > 30) sections.push(`- ... and ${depNames.length - 30} more`);\n }\n if (Object.keys(manifest.metadata).length > 0) {\n sections.push(`- Metadata: ${JSON.stringify(manifest.metadata)}`);\n }\n sections.push('');\n }\n }\n\n // Package info (JS/TS — backward compat)\n if (analysis.packageJson) {\n const pkg = analysis.packageJson;\n sections.push(`**Project:** ${pkg.name || '(unnamed)'}`);\n sections.push(`**Module system:** ${pkg.type ?? 'commonjs (default)'}`);\n sections.push('');\n\n // Dependencies\n const depNames = Object.keys(pkg.dependencies);\n if (depNames.length > 0) {\n sections.push('### Dependencies');\n sections.push(depNames.map((d) => `- \\`${d}\\`: ${pkg.dependencies[d]}`).join('\\n'));\n sections.push('');\n }\n\n const devDepNames = Object.keys(pkg.devDependencies);\n if (devDepNames.length > 0) {\n sections.push('### Dev Dependencies');\n sections.push(devDepNames.map((d) => `- \\`${d}\\`: ${pkg.devDependencies[d]}`).join('\\n'));\n sections.push('');\n }\n\n // Scripts\n const scriptEntries = Object.entries(pkg.scripts);\n if (scriptEntries.length > 0) {\n sections.push('### Scripts');\n sections.push(scriptEntries.map(([k, v]) => `- \\`${k}\\`: \\`${v}\\``).join('\\n'));\n sections.push('');\n }\n } else {\n sections.push('*No package.json found.*');\n sections.push('');\n }\n\n // Structure\n sections.push('### Project Structure');\n sections.push(`- TypeScript: ${analysis.structure.hasTypescript ? 'yes' : 'no'}`);\n sections.push(`- src/ directory: ${analysis.structure.hasSrcDir ? 'yes' : 'no'}`);\n sections.push(`- Test directory: ${analysis.structure.hasTestDir ? 'yes' : 'no'}`);\n if (analysis.structure.entryPoints.length > 0) {\n sections.push(`- Entry points: ${analysis.structure.entryPoints.map((e) => `\\`${e}\\``).join(', ')}`);\n }\n if (analysis.structure.configFiles.length > 0) {\n sections.push(`- Config files: ${analysis.structure.configFiles.map((f) => `\\`${f}\\``).join(', ')}`);\n }\n sections.push('');\n\n // Patterns\n sections.push('### Detected Patterns');\n sections.push(`- Import style: **${analysis.patterns.importStyle}**`);\n sections.push(`- Test framework: ${analysis.patterns.testFramework ?? 'none detected'}`);\n sections.push(`- Linter: ${analysis.patterns.linter ?? 'none detected'}`);\n sections.push(`- Formatter: ${analysis.patterns.formatter ?? 'none detected'}`);\n sections.push(`- Build tool: ${analysis.patterns.buildTool ?? 'none detected'}`);\n sections.push('');\n\n // Existing utilities\n if (analysis.existingUtils.length > 0) {\n sections.push('### Existing Utilities (reuse before creating new ones)');\n for (const util of analysis.existingUtils) {\n sections.push(`- **\\`${util.file}\\`**: ${util.exports.map((e) => `\\`${e}\\``).join(', ')}`);\n }\n sections.push('');\n }\n\n // Key guidance\n sections.push('### Key Guidance');\n if (analysis.patterns.importStyle === 'esm') {\n sections.push('- Use ESM imports (`import`/`export`). Use `.js` extensions in relative imports if TypeScript with bundler resolution.');\n } else if (analysis.patterns.importStyle === 'commonjs') {\n sections.push('- Use CommonJS (`require`/`module.exports`).');\n } else {\n sections.push('- Mixed import styles detected. Prefer the dominant style in the module you are editing.');\n }\n if (analysis.packageJson) {\n sections.push('- Do NOT run `npm install` for packages already listed in dependencies or devDependencies.');\n }\n if (analysis.patterns.testFramework) {\n sections.push(`- Write tests using **${analysis.patterns.testFramework}** (already installed).`);\n }\n if (analysis.patterns.buildTool) {\n sections.push(`- Build with **${analysis.patterns.buildTool}** (already configured).`);\n }\n\n return sections.join('\\n');\n}\n","import { z } from 'zod';\nimport {\n getMeeting,\n listMeetings,\n listAgentsByMeeting,\n listWorkersByLeader,\n} from '../storage/index.js';\n\nexport const getMeetingStatusSchema = {\n meetingId: z\n .string()\n .optional()\n .describe('Specific meeting ID, or omit for all active'),\n};\n\nexport async function getMeetingStatusHandler({\n meetingId,\n}: {\n meetingId?: string;\n}): Promise<{ content: { type: 'text'; text: string }[]; isError?: boolean }> {\n try {\n if (meetingId) {\n const meeting = getMeeting(meetingId);\n if (!meeting) {\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(\n { error: `Meeting not found: ${meetingId}` },\n null,\n 2,\n ),\n },\n ],\n isError: true,\n };\n }\n\n const agents = listAgentsByMeeting(meetingId);\n const workers = agents.flatMap((agent) =>\n listWorkersByLeader(agent.id),\n );\n\n const result = {\n meeting,\n agents,\n workers,\n };\n\n return {\n content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],\n };\n }\n\n // Return all active meetings summary\n const allMeetings = listMeetings();\n const activeMeetings = allMeetings.filter(\n (m) =>\n !['completed', 'cancelled', 'failed', 'reported', 'compacted'].includes(\n m.status,\n ),\n );\n\n const result = {\n totalMeetings: allMeetings.length,\n activeMeetings: activeMeetings.map((m) => ({\n id: m.id,\n topic: m.topic,\n status: m.status,\n phase: m.phase,\n startedAt: m.startedAt,\n })),\n };\n\n return {\n content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],\n };\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n return {\n content: [\n { type: 'text', text: JSON.stringify({ error: message }, null, 2) },\n ],\n isError: true,\n };\n }\n}\n","import { z } from 'zod';\nimport { getMinutesByMeeting } from '../storage/index.js';\n\nexport const getMinutesSchema = {\n meetingId: z.string().describe('Meeting ID'),\n format: z\n .enum(['full', 'summary', 'tasks_only'])\n .default('full')\n .optional()\n .describe('Output format'),\n};\n\nexport async function getMinutesHandler({\n meetingId,\n format,\n}: {\n meetingId: string;\n format?: 'full' | 'summary' | 'tasks_only';\n}): Promise<{ content: { type: 'text'; text: string }[]; isError?: boolean }> {\n try {\n const minutes = getMinutesByMeeting(meetingId);\n if (!minutes) {\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(\n { error: `No minutes found for meeting: ${meetingId}` },\n null,\n 2,\n ),\n },\n ],\n isError: true,\n };\n }\n\n const effectiveFormat = format ?? 'full';\n\n let result: unknown;\n\n switch (effectiveFormat) {\n case 'full':\n result = {\n id: minutes.id,\n meetingId: minutes.meetingId,\n format: minutes.format,\n content: minutes.content,\n actionItems: minutes.actionItems,\n createdAt: minutes.createdAt,\n };\n break;\n\n case 'summary': {\n // Extract a summary: first 500 chars of content + action item count\n const summaryContent =\n minutes.content.length > 500\n ? minutes.content.slice(0, 500) + '...'\n : minutes.content;\n result = {\n id: minutes.id,\n meetingId: minutes.meetingId,\n summary: summaryContent,\n actionItemCount: minutes.actionItems.length,\n createdAt: minutes.createdAt,\n };\n break;\n }\n\n case 'tasks_only':\n result = {\n meetingId: minutes.meetingId,\n actionItems: minutes.actionItems,\n totalTasks: minutes.actionItems.length,\n };\n break;\n }\n\n return {\n content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],\n };\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n return {\n content: [\n { type: 'text', text: JSON.stringify({ error: message }, null, 2) },\n ],\n isError: true,\n };\n }\n}\n","import { z } from 'zod';\nimport { Compactor } from '../meeting/compactor.js';\n\nexport const compactMinutesSchema = {\n meetingId: z.string().describe('Meeting ID'),\n additionalInstructions: z\n .string()\n .optional()\n .describe('Additional instructions for compaction'),\n};\n\nexport async function compactMinutesHandler({\n meetingId,\n additionalInstructions,\n}: {\n meetingId: string;\n additionalInstructions?: string;\n}): Promise<{ content: { type: 'text'; text: string }[]; isError?: boolean }> {\n try {\n const compactor = new Compactor();\n const tasks = await compactor.compactMinutes(\n meetingId,\n additionalInstructions,\n );\n\n const result = {\n meetingId,\n tasksGenerated: tasks.length,\n tasks,\n };\n\n return {\n content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],\n };\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n return {\n content: [\n { type: 'text', text: JSON.stringify({ error: message }, null, 2) },\n ],\n isError: true,\n };\n }\n}\n","/**\n * Compacts meeting minutes into a structured task list per department.\n *\n * Assigns departments and priorities based on keyword analysis.\n */\n\nimport { v4 as uuidv4 } from 'uuid';\nimport { getMinutesByMeeting, createMinutes } from '../storage/index.js';\nimport { getDb } from '../storage/db.js';\nimport type { ActionItem, Department, MinutesRecord } from '../types/index.js';\nimport { logger } from '../utils/logger.js';\n\n// ---------------------------------------------------------------------------\n// Keyword → department mapping\n// ---------------------------------------------------------------------------\n\nconst DEPARTMENT_KEYWORDS: Record<Department, string[]> = {\n architecture: [\n 'schema', 'design', 'architecture', 'blueprint', 'dependency',\n 'api design', 'system design', '아키텍처', '설계',\n ],\n engineering: [\n 'implement', 'code', 'develop', 'build', 'refactor', 'fix',\n 'feature', 'module', '구현', '개발', '코드',\n ],\n qa: [\n 'test', 'quality', 'coverage', 'security', 'audit', 'performance',\n 'regression', 'validation', '테스트', '검증', '품질',\n ],\n product: [\n 'requirement', 'user story', 'acceptance criteria', 'stakeholder',\n 'priority', 'roadmap', 'scope', '요구사항', '사용자',\n ],\n research: [\n 'research', 'explore', 'investigate', 'benchmark', 'compare',\n 'evaluate', 'poc', 'prototype', '조사', '탐색',\n ],\n};\n\n// ---------------------------------------------------------------------------\n// Keyword → priority mapping\n// ---------------------------------------------------------------------------\n\nconst PRIORITY_KEYWORDS: Record<ActionItem['priority'], string[]> = {\n critical: [\n 'critical', 'urgent', 'blocker', 'blocking', 'asap', 'immediately',\n '긴급', '즉시', 'p0',\n ],\n high: [\n 'high priority', 'important', 'must', 'required', 'essential',\n '중요', '필수', 'p1',\n ],\n medium: [\n 'medium', 'should', 'moderate', '보통', 'p2',\n ],\n low: [\n 'low priority', 'nice to have', 'optional', 'consider',\n '낮음', '선택', 'p3',\n ],\n};\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction detectDepartment(text: string): Department {\n const lower = text.toLowerCase();\n let bestDept: Department = 'engineering';\n let bestScore = 0;\n\n for (const [dept, keywords] of Object.entries(DEPARTMENT_KEYWORDS) as [Department, string[]][]) {\n const score = keywords.reduce(\n (acc, kw) => acc + (lower.includes(kw.toLowerCase()) ? 1 : 0),\n 0,\n );\n if (score > bestScore) {\n bestScore = score;\n bestDept = dept;\n }\n }\n\n return bestDept;\n}\n\nfunction detectPriority(text: string): ActionItem['priority'] {\n const lower = text.toLowerCase();\n\n // Check from highest to lowest — first match wins\n for (const priority of ['critical', 'high', 'medium', 'low'] as const) {\n const keywords = PRIORITY_KEYWORDS[priority];\n if (keywords.some((kw) => lower.includes(kw.toLowerCase()))) {\n return priority;\n }\n }\n\n return 'medium';\n}\n\nconst LEADER_ROLE_FOR_DEPT: Record<Department, string> = {\n architecture: 'arch-leader',\n engineering: 'eng-leader',\n qa: 'qa-leader',\n product: 'pm-leader',\n research: 'research-leader',\n};\n\n// ---------------------------------------------------------------------------\n// Compactor\n// ---------------------------------------------------------------------------\n\nexport class Compactor {\n /**\n * Compact minutes into actionable, department-assigned tasks.\n *\n * 1. Load minutes for the meeting\n * 2. Parse action items from the minutes content\n * 3. Assign each to a department based on keywords\n * 4. Set priorities based on keywords\n * 5. Save updated action items to minutes record\n * 6. Return the structured task list\n */\n async compactMinutes(\n meetingId: string,\n additionalInstructions?: string,\n ): Promise<ActionItem[]> {\n logger.info('Compacting minutes', { meetingId });\n\n // 1. Load existing minutes\n const minutes = getMinutesByMeeting(meetingId);\n if (!minutes) {\n throw new Error(`No minutes found for meeting: ${meetingId}`);\n }\n\n // 2–4. Refine existing action items with department + priority detection\n const refinedItems: ActionItem[] = minutes.actionItems.map((item) => {\n const fullText = `${item.title} ${item.description} ${additionalInstructions ?? ''}`;\n const department = detectDepartment(fullText);\n const priority = detectPriority(fullText);\n\n return {\n ...item,\n assignedDepartment: department,\n assignedRole: LEADER_ROLE_FOR_DEPT[department],\n priority,\n };\n });\n\n // If there are no existing action items, try to extract from minutes content\n if (refinedItems.length === 0) {\n const extracted = this.extractFromContent(minutes.content);\n refinedItems.push(...extracted);\n }\n\n // 5. Update the minutes record in the DB\n const db = getDb();\n db.prepare('UPDATE minutes SET action_items = ? WHERE id = ?').run(\n JSON.stringify(refinedItems),\n minutes.id,\n );\n\n logger.info('Minutes compacted', {\n meetingId,\n actionItemCount: refinedItems.length,\n } as Record<string, unknown>);\n\n // 6. Return the structured task list\n return refinedItems;\n }\n\n // -------------------------------------------------------------------------\n // Fallback extraction from raw minutes content\n // -------------------------------------------------------------------------\n\n private extractFromContent(content: string): ActionItem[] {\n const items: ActionItem[] = [];\n const lines = content.split('\\n');\n\n for (const line of lines) {\n const trimmed = line.trim();\n // Look for lines that start with \"- \" or numbered items under action sections\n if (\n trimmed.startsWith('- ') &&\n trimmed.length > 5 &&\n trimmed !== '- None' &&\n trimmed !== '- None recorded' &&\n trimmed !== '- No action items identified' &&\n trimmed !== '- No action items recorded'\n ) {\n const text = trimmed.slice(2);\n const department = detectDepartment(text);\n const priority = detectPriority(text);\n\n items.push({\n id: uuidv4(),\n title: text.slice(0, 80),\n description: text,\n assignedDepartment: department,\n assignedRole: LEADER_ROLE_FOR_DEPT[department],\n priority,\n dependencies: [],\n acceptanceCriteria: [],\n });\n }\n }\n\n return items;\n }\n}\n","import { z } from 'zod';\nimport { getTasksFromMinutes } from '../storage/index.js';\nimport { WorkerManager } from '../orchestrator/worker-manager.js';\nimport type { TaskAssignment } from '../types/index.js';\n\nexport const executeTasksSchema = {\n meetingId: z.string().describe('Meeting ID'),\n taskIds: z\n .array(z.string())\n .optional()\n .describe('Specific tasks to execute, or all'),\n};\n\nexport async function executeTasksHandler({\n meetingId,\n taskIds,\n}: {\n meetingId: string;\n taskIds?: string[];\n}): Promise<{ content: { type: 'text'; text: string }[]; isError?: boolean }> {\n try {\n const allTasks = getTasksFromMinutes(meetingId);\n\n if (allTasks.length === 0) {\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(\n {\n error: `No tasks found for meeting: ${meetingId}. Run compact-minutes first.`,\n },\n null,\n 2,\n ),\n },\n ],\n isError: true,\n };\n }\n\n // Filter tasks if specific IDs provided\n const tasksToExecute = taskIds\n ? allTasks.filter((t) => taskIds.includes(t.id))\n : allTasks;\n\n if (tasksToExecute.length === 0) {\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(\n { error: 'No matching tasks found for the provided task IDs.' },\n null,\n 2,\n ),\n },\n ],\n isError: true,\n };\n }\n\n // Group tasks by department\n const tasksByDepartment = new Map<string, typeof tasksToExecute>();\n for (const task of tasksToExecute) {\n const dept = task.assignedDepartment;\n if (!tasksByDepartment.has(dept)) {\n tasksByDepartment.set(dept, []);\n }\n tasksByDepartment.get(dept)!.push(task);\n }\n\n const workerManager = new WorkerManager();\n const executionResults: Array<{\n department: string;\n taskCount: number;\n workers: Array<{\n id: string;\n status: string;\n taskDescription: string;\n outputResult: string | null;\n errorMessage: string | null;\n }>;\n }> = [];\n\n // Execute tasks per department\n for (const [department, tasks] of tasksByDepartment) {\n const assignments: TaskAssignment[] = tasks.map((task) => ({\n workerId: task.id,\n description: `${task.title}: ${task.description}`,\n inputPaths: [],\n outputPath: '',\n dependencies: task.dependencies,\n status: 'pending' as const,\n result: null,\n }));\n\n // Use a synthetic leader ID based on the department\n const leaderId = `${department}-leader-${meetingId}`;\n const workers = await workerManager.spawnWorkers(\n leaderId,\n meetingId,\n assignments,\n );\n\n const completedWorkers = await workerManager.executeWorkers(workers);\n\n executionResults.push({\n department,\n taskCount: tasks.length,\n workers: completedWorkers.map((w) => ({\n id: w.id,\n status: w.status,\n taskDescription: w.taskDescription,\n outputResult: w.outputResult,\n errorMessage: w.errorMessage,\n })),\n });\n }\n\n const totalWorkers = executionResults.reduce(\n (acc, r) => acc + r.workers.length,\n 0,\n );\n const completedCount = executionResults.reduce(\n (acc, r) =>\n acc + r.workers.filter((w) => w.status === 'completed').length,\n 0,\n );\n const failedCount = executionResults.reduce(\n (acc, r) => acc + r.workers.filter((w) => w.status === 'failed').length,\n 0,\n );\n\n const result = {\n meetingId,\n summary: {\n totalTasks: tasksToExecute.length,\n totalWorkers,\n completed: completedCount,\n failed: failedCount,\n },\n departments: executionResults,\n };\n\n return {\n content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],\n };\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n return {\n content: [\n { type: 'text', text: JSON.stringify({ error: message }, null, 2) },\n ],\n isError: true,\n };\n }\n}\n","import { v4 as uuidv4 } from 'uuid';\nimport type { WorkerRecord, TaskAssignment, TaskType, Department } from '../types/index.js';\nimport {\n createWorker,\n updateWorker,\n listWorkersByLeader,\n} from '../storage/index.js';\nimport { createAgentConfig } from '../agents/agent-factory.js';\nimport { invokeClaude, buildInvokeOptions } from '../agents/claude-invoker.js';\nimport { getLeaderSystemPrompt } from '../agents/leader-prompts.js';\nimport { buildWorkerPrompt } from '../agents/worker-prompts.js';\nimport { eventBus } from './event-bus.js';\nimport { logger } from '../utils/logger.js';\n\n// ---------------------------------------------------------------------------\n// Worker execution — uses Claude CLI or falls back to mock\n// ---------------------------------------------------------------------------\n\n/**\n * Execute a worker by invoking Claude CLI as a subprocess.\n *\n * When COLESLAW_MOCK=1 is set or the `claude` CLI is not available, the\n * underlying `invokeClaude` function automatically falls back to mock responses.\n */\nasync function executeWorkerAgent(worker: WorkerRecord): Promise<string> {\n // Infer the department from the task type or default to engineering\n const department: Department = inferDepartment(worker);\n\n // Infer a worker role from the task type\n const workerRole = inferWorkerRole(worker);\n\n const agentConfig = createAgentConfig({\n tier: 'worker',\n role: workerRole,\n department,\n task: worker.taskDescription,\n context: worker.inputContext ?? undefined,\n });\n\n const systemPrompt = buildWorkerPrompt({\n workerType: workerRole as import('../types/index.js').WorkerType,\n department,\n task: worker.taskDescription,\n context: worker.inputContext ?? undefined,\n });\n\n const prompt =\n `Execute the following task:\\n\\n` +\n `Task: ${worker.taskDescription}\\n` +\n (worker.inputContext ? `\\nContext: ${worker.inputContext}\\n` : '') +\n `\\nProvide a clear, structured result.`;\n\n const invokeOpts = buildInvokeOptions(agentConfig, prompt, systemPrompt);\n\n // Workers get a 5-minute timeout\n invokeOpts.timeoutMs = 300_000;\n\n const result = await invokeClaude(invokeOpts);\n\n if (!result.success) {\n throw new Error(result.error ?? 'Worker agent invocation failed');\n }\n\n return result.output;\n}\n\n/**\n * Infer the department a worker belongs to based on its task type.\n */\nfunction inferDepartment(worker: WorkerRecord): Department {\n switch (worker.taskType) {\n case 'research':\n return 'research';\n case 'testing':\n return 'qa';\n case 'analysis':\n return 'architecture';\n case 'implementation':\n default:\n return 'engineering';\n }\n}\n\n/**\n * Infer a specific worker role from the task description and type.\n */\nfunction inferWorkerRole(worker: WorkerRecord): string {\n const desc = worker.taskDescription.toLowerCase();\n\n // Architecture roles\n if (desc.includes('schema') || desc.includes('data model')) return 'schema-designer';\n if (desc.includes('api') || desc.includes('endpoint')) return 'api-designer';\n if (desc.includes('dependency') || desc.includes('coupling')) return 'dependency-analyzer';\n\n // QA roles\n if (desc.includes('test')) return 'test-writer';\n if (desc.includes('security') || desc.includes('audit')) return 'security-auditor';\n if (desc.includes('performance') || desc.includes('benchmark')) return 'perf-tester';\n\n // Research roles\n if (desc.includes('research') || desc.includes('explore') || desc.includes('investigate')) return 'code-explorer';\n if (desc.includes('document') || desc.includes('search')) return 'doc-searcher';\n\n // Engineering roles\n if (desc.includes('fix') || desc.includes('bug')) return 'bug-fixer';\n if (desc.includes('refactor')) return 'refactorer';\n\n // Default to feature-dev for implementation tasks\n return 'feature-dev';\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction inferTaskType(description: string): TaskType {\n const lower = description.toLowerCase();\n if (lower.includes('research') || lower.includes('explore') || lower.includes('search')) {\n return 'research';\n }\n if (lower.includes('test') || lower.includes('audit') || lower.includes('benchmark')) {\n return 'testing';\n }\n if (lower.includes('analys') || lower.includes('design') || lower.includes('schema')) {\n return 'analysis';\n }\n return 'implementation';\n}\n\n// ---------------------------------------------------------------------------\n// WorkerManager\n// ---------------------------------------------------------------------------\n\nexport class WorkerManager {\n // ---- spawn workers ------------------------------------------------------\n\n /**\n * Spawn a batch of workers on behalf of a leader.\n *\n * Each task assignment is persisted to SQLite and an `agent_spawned` event is\n * emitted. The returned records are in `pending` status.\n */\n async spawnWorkers(\n leaderId: string,\n meetingId: string,\n tasks: TaskAssignment[],\n ): Promise<WorkerRecord[]> {\n const workers: WorkerRecord[] = [];\n\n for (const task of tasks) {\n const worker = createWorker({\n leaderId,\n meetingId,\n taskDescription: task.description,\n taskType: inferTaskType(task.description),\n inputContext: task.inputPaths.length > 0 ? task.inputPaths.join(', ') : null,\n outputResult: null,\n errorMessage: null,\n dependencies: task.dependencies,\n });\n\n workers.push(worker);\n\n logger.info(`Spawned worker for leader ${leaderId}`, {\n agentId: worker.id,\n meetingId,\n department: 'worker',\n });\n\n eventBus.emitAgentEvent({\n kind: 'agent_spawned',\n agentId: worker.id,\n agentType: 'worker',\n parentId: leaderId,\n label: task.description.slice(0, 60),\n department: 'engineering', // Workers inherit; refined later if needed\n });\n }\n\n return workers;\n }\n\n // ---- execute workers ----------------------------------------------------\n\n /**\n * Execute a list of workers, respecting dependency ordering.\n *\n * - Workers with no unresolved dependencies run in parallel.\n * - Workers whose dependencies are all completed run next.\n * - Continues until all workers are done or a dependency cycle is detected.\n */\n async executeWorkers(workers: WorkerRecord[]): Promise<WorkerRecord[]> {\n const completed = new Set<string>();\n const results: WorkerRecord[] = [];\n const pending = new Map(workers.map((w) => [w.id, w]));\n\n while (pending.size > 0) {\n // Find workers whose dependencies are all satisfied\n const ready: WorkerRecord[] = [];\n for (const worker of pending.values()) {\n const depsReady = worker.dependencies.every((dep) => completed.has(dep));\n if (depsReady) {\n ready.push(worker);\n }\n }\n\n if (ready.length === 0) {\n // All remaining workers have unsatisfied deps — break to avoid infinite loop\n logger.warn('Dependency cycle or unsatisfiable deps detected; failing remaining workers');\n for (const worker of pending.values()) {\n const failed = updateWorker(worker.id, {\n status: 'failed',\n errorMessage: 'Unresolvable dependency',\n completedAt: Date.now(),\n });\n results.push(failed ?? worker);\n\n eventBus.emitAgentEvent({\n kind: 'task_completed',\n agentId: worker.id,\n result: 'failure',\n });\n }\n break;\n }\n\n // Execute ready batch in parallel\n const batchResults = await Promise.allSettled(\n ready.map(async (worker) => {\n // Mark running\n updateWorker(worker.id, { status: 'running' });\n eventBus.emitAgentEvent({\n kind: 'state_changed',\n agentId: worker.id,\n from: 'idle',\n to: 'working',\n });\n\n try {\n const output = await executeWorkerAgent(worker);\n const updated = updateWorker(worker.id, {\n status: 'completed',\n outputResult: output,\n completedAt: Date.now(),\n costUsd: 0.01, // Approximate cost; real cost tracked by CLI\n });\n\n eventBus.emitAgentEvent({\n kind: 'task_completed',\n agentId: worker.id,\n result: 'success',\n });\n\n return updated ?? worker;\n } catch (err) {\n const errorMsg = err instanceof Error ? err.message : String(err);\n const updated = updateWorker(worker.id, {\n status: 'failed',\n errorMessage: errorMsg,\n completedAt: Date.now(),\n });\n\n eventBus.emitAgentEvent({\n kind: 'task_completed',\n agentId: worker.id,\n result: 'failure',\n });\n\n return updated ?? worker;\n }\n }),\n );\n\n for (let i = 0; i < ready.length; i++) {\n const worker = ready[i];\n pending.delete(worker.id);\n completed.add(worker.id);\n\n const settlement = batchResults[i];\n if (settlement.status === 'fulfilled') {\n results.push(settlement.value);\n } else {\n results.push(worker);\n }\n }\n }\n\n return results;\n }\n\n // ---- status query -------------------------------------------------------\n\n /**\n * Get the current status of all workers under a given leader.\n */\n getWorkerStatus(leaderId: string): WorkerRecord[] {\n return listWorkersByLeader(leaderId);\n }\n}\n","import { getAgentTree } from '../storage/index.js';\n\nexport async function getAgentTreeHandler(): Promise<{\n content: { type: 'text'; text: string }[];\n isError?: boolean;\n}> {\n try {\n const tree = getAgentTree('orchestrator-root');\n\n const result = {\n root: tree,\n hasAgents: tree !== null,\n };\n\n return {\n content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],\n };\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n return {\n content: [\n { type: 'text', text: JSON.stringify({ error: message }, null, 2) },\n ],\n isError: true,\n };\n }\n}\n","import { z } from 'zod';\nimport { getMention, updateMention } from '../storage/index.js';\nimport { eventBus } from '../orchestrator/event-bus.js';\n\nexport const respondToMentionSchema = {\n mentionId: z.string().describe('ID of the mention to respond to'),\n decision: z.string().describe('The decision made by the user'),\n reasoning: z.string().optional().describe('Optional reasoning for the decision'),\n};\n\nexport async function respondToMentionHandler({\n mentionId,\n decision,\n reasoning,\n}: {\n mentionId: string;\n decision: string;\n reasoning?: string;\n}): Promise<{ content: { type: 'text'; text: string }[]; isError?: boolean }> {\n try {\n const mention = getMention(mentionId);\n\n if (!mention) {\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(\n { error: `Mention not found: ${mentionId}` },\n null,\n 2,\n ),\n },\n ],\n isError: true,\n };\n }\n\n if (mention.status === 'resolved') {\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(\n { error: `Mention already resolved: ${mentionId}` },\n null,\n 2,\n ),\n },\n ],\n isError: true,\n };\n }\n\n const resolved = updateMention(mentionId, {\n status: 'resolved',\n userDecision: decision,\n userReasoning: reasoning ?? null,\n resolvedAt: Date.now(),\n });\n\n eventBus.emitAgentEvent({\n kind: 'mention_resolved',\n mentionId,\n decision,\n });\n\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(\n { success: true, mention: resolved },\n null,\n 2,\n ),\n },\n ],\n };\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n return {\n content: [\n { type: 'text', text: JSON.stringify({ error: message }, null, 2) },\n ],\n isError: true,\n };\n }\n}\n","import { z } from 'zod';\nimport {\n listPendingMentions,\n listMentionsByMeeting,\n} from '../storage/index.js';\nimport type { MentionRecord } from '../types/index.js';\n\nexport const getMentionsSchema = {\n status: z\n .enum(['pending', 'resolved', 'all'])\n .default('pending')\n .optional()\n .describe('Filter mentions by status'),\n meetingId: z\n .string()\n .optional()\n .describe('Filter mentions by meeting ID'),\n};\n\nexport async function getMentionsHandler({\n status,\n meetingId,\n}: {\n status?: 'pending' | 'resolved' | 'all';\n meetingId?: string;\n}): Promise<{ content: { type: 'text'; text: string }[]; isError?: boolean }> {\n try {\n const effectiveStatus = status ?? 'pending';\n let mentions: MentionRecord[];\n\n if (meetingId) {\n // Get all mentions for this meeting, then filter by status\n const allForMeeting = listMentionsByMeeting(meetingId);\n if (effectiveStatus === 'all') {\n mentions = allForMeeting;\n } else {\n mentions = allForMeeting.filter((m) => m.status === effectiveStatus);\n }\n } else if (effectiveStatus === 'pending') {\n mentions = listPendingMentions();\n } else if (effectiveStatus === 'resolved') {\n // listPendingMentions only returns pending; for resolved we need to\n // get all and filter. Since there is no dedicated storage function for\n // resolved mentions, we use listMentionsByMeeting with no meetingId —\n // but that requires a meetingId. Instead we get pending and note the\n // limitation, or we query directly.\n // For a clean approach, list all meetings' mentions by getting pending\n // and noting this is a filtered view.\n // Actually, we can use the DB directly through the existing functions.\n // The simplest correct approach: get all pending and return empty since\n // we want resolved. But that's wrong. Let's just get all mentions.\n // Since there's no listAllMentions, we'll import getDb and query directly.\n const { getDb } = await import('../storage/db.js');\n const db = getDb();\n interface MentionRow {\n id: string;\n meeting_id: string;\n agenda_item: string | null;\n summary: string;\n options: string;\n urgency: string;\n status: string;\n user_decision: string | null;\n user_reasoning: string | null;\n created_at: number;\n resolved_at: number | null;\n }\n const rows = db\n .prepare(\"SELECT * FROM mentions WHERE status = 'resolved' ORDER BY created_at ASC\")\n .all() as MentionRow[];\n mentions = rows.map((row) => ({\n id: row.id,\n meetingId: row.meeting_id,\n agendaItem: row.agenda_item,\n summary: row.summary,\n options: JSON.parse(row.options),\n urgency: row.urgency as MentionRecord['urgency'],\n status: row.status as MentionRecord['status'],\n userDecision: row.user_decision,\n userReasoning: row.user_reasoning,\n createdAt: row.created_at,\n resolvedAt: row.resolved_at,\n }));\n } else {\n // 'all'\n const { getDb } = await import('../storage/db.js');\n const db = getDb();\n interface MentionRow {\n id: string;\n meeting_id: string;\n agenda_item: string | null;\n summary: string;\n options: string;\n urgency: string;\n status: string;\n user_decision: string | null;\n user_reasoning: string | null;\n created_at: number;\n resolved_at: number | null;\n }\n const rows = db\n .prepare('SELECT * FROM mentions ORDER BY created_at ASC')\n .all() as MentionRow[];\n mentions = rows.map((row) => ({\n id: row.id,\n meetingId: row.meeting_id,\n agendaItem: row.agenda_item,\n summary: row.summary,\n options: JSON.parse(row.options),\n urgency: row.urgency as MentionRecord['urgency'],\n status: row.status as MentionRecord['status'],\n userDecision: row.user_decision,\n userReasoning: row.user_reasoning,\n createdAt: row.created_at,\n resolvedAt: row.resolved_at,\n }));\n }\n\n const result = {\n count: mentions.length,\n status: effectiveStatus,\n ...(meetingId ? { meetingId } : {}),\n mentions,\n };\n\n return {\n content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],\n };\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n return {\n content: [\n { type: 'text', text: JSON.stringify({ error: message }, null, 2) },\n ],\n isError: true,\n };\n }\n}\n","import { z } from 'zod';\nimport {\n getMeeting,\n updateMeeting,\n listAgentsByMeeting,\n updateAgent,\n listWorkersByLeader,\n updateWorker,\n} from '../storage/index.js';\nimport { eventBus } from '../orchestrator/event-bus.js';\n\nexport const cancelMeetingSchema = {\n meetingId: z.string().describe('ID of the meeting to cancel'),\n reason: z.string().optional().describe('Reason for cancellation'),\n};\n\nexport async function cancelMeetingHandler({\n meetingId,\n reason,\n}: {\n meetingId: string;\n reason?: string;\n}): Promise<{ content: { type: 'text'; text: string }[]; isError?: boolean }> {\n try {\n const meeting = getMeeting(meetingId);\n\n if (!meeting) {\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(\n { error: `Meeting not found: ${meetingId}` },\n null,\n 2,\n ),\n },\n ],\n isError: true,\n };\n }\n\n if (meeting.status === 'completed' || meeting.status === 'cancelled') {\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(\n {\n error: `Meeting cannot be cancelled: current status is '${meeting.status}'`,\n },\n null,\n 2,\n ),\n },\n ],\n isError: true,\n };\n }\n\n // Update meeting status to cancelled\n updateMeeting(meetingId, { status: 'cancelled', completedAt: Date.now() });\n\n // Find all agents for this meeting and mark them as completed\n const agents = listAgentsByMeeting(meetingId);\n let agentsCancelled = 0;\n let workersFailed = 0;\n\n for (const agent of agents) {\n if (agent.status !== 'completed' && agent.status !== 'failed') {\n updateAgent(agent.id, { status: 'completed', completedAt: Date.now() });\n agentsCancelled++;\n\n eventBus.emitAgentEvent({\n kind: 'state_changed',\n agentId: agent.id,\n from: agent.status,\n to: 'completed',\n });\n }\n\n // Find all workers for this agent (leader) and mark them as failed\n const workers = listWorkersByLeader(agent.id);\n for (const worker of workers) {\n if (worker.status !== 'completed' && worker.status !== 'failed') {\n updateWorker(worker.id, {\n status: 'failed',\n errorMessage: reason ?? 'Meeting cancelled',\n completedAt: Date.now(),\n });\n workersFailed++;\n\n eventBus.emitAgentEvent({\n kind: 'task_completed',\n agentId: worker.id,\n result: 'failure',\n });\n }\n }\n }\n\n const result = {\n success: true,\n meetingId,\n previousStatus: meeting.status,\n reason: reason ?? 'No reason provided',\n agentsCancelled,\n workersFailed,\n };\n\n return {\n content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],\n };\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n return {\n content: [\n { type: 'text', text: JSON.stringify({ error: message }, null, 2) },\n ],\n isError: true,\n };\n }\n}\n","import { z } from 'zod';\nimport { listMeetings } from '../storage/index.js';\nimport type { MeetingStatus } from '../types/index.js';\n\nexport const listMeetingsSchema = {\n status: z\n .enum(['pending', 'running', 'completed', 'cancelled', 'failed', 'all'])\n .default('all')\n .optional()\n .describe('Filter meetings by status'),\n limit: z\n .number()\n .default(20)\n .optional()\n .describe('Maximum number of meetings to return'),\n};\n\n// Map the user-facing \"running\" status to the internal statuses that represent\n// an active/running meeting.\nconst RUNNING_STATUSES: MeetingStatus[] = [\n 'convening',\n 'opening',\n 'discussion',\n 'synthesis',\n 'minutes-generation',\n 'executing',\n 'aggregation',\n 'waiting-for-user',\n];\n\nexport async function listMeetingsHandler({\n status,\n limit,\n}: {\n status?: 'pending' | 'running' | 'completed' | 'cancelled' | 'failed' | 'all';\n limit?: number;\n}): Promise<{ content: { type: 'text'; text: string }[]; isError?: boolean }> {\n try {\n const effectiveStatus = status ?? 'all';\n const effectiveLimit = limit ?? 20;\n\n let meetings;\n\n if (effectiveStatus === 'all') {\n meetings = listMeetings();\n } else if (effectiveStatus === 'running') {\n // \"running\" maps to multiple internal statuses\n const all = listMeetings();\n meetings = all.filter((m) => RUNNING_STATUSES.includes(m.status));\n } else {\n meetings = listMeetings(effectiveStatus as MeetingStatus);\n }\n\n // Apply limit\n const limited = meetings.slice(0, effectiveLimit);\n\n const result = {\n total: meetings.length,\n returned: limited.length,\n status: effectiveStatus,\n meetings: limited.map((m) => ({\n id: m.id,\n topic: m.topic,\n status: m.status,\n phase: m.phase,\n participantCount: m.participantIds.length,\n startedAt: m.startedAt,\n })),\n };\n\n return {\n content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],\n };\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n return {\n content: [\n { type: 'text', text: JSON.stringify({ error: message }, null, 2) },\n ],\n isError: true,\n };\n }\n}\n","import { z } from 'zod';\nimport {\n getMeeting,\n getMinutesByMeeting,\n listAgentsByMeeting,\n listWorkersByLeader,\n} from '../storage/index.js';\n\nexport const getTaskReportSchema = {\n meetingId: z.string().describe('ID of the meeting to generate a report for'),\n};\n\nexport async function getTaskReportHandler({\n meetingId,\n}: {\n meetingId: string;\n}): Promise<{ content: { type: 'text'; text: string }[]; isError?: boolean }> {\n try {\n const meeting = getMeeting(meetingId);\n if (!meeting) {\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(\n { error: `Meeting not found: ${meetingId}` },\n null,\n 2,\n ),\n },\n ],\n isError: true,\n };\n }\n\n const minutes = getMinutesByMeeting(meetingId);\n const agents = listAgentsByMeeting(meetingId);\n\n // Collect all workers grouped by leader/department\n const departmentBreakdowns: Array<{\n department: string;\n leaderId: string;\n leaderRole: string;\n workers: Array<{\n id: string;\n taskDescription: string;\n status: string;\n costUsd: number;\n errorMessage: string | null;\n }>;\n completed: number;\n failed: number;\n pending: number;\n totalCost: number;\n }> = [];\n\n let totalCompleted = 0;\n let totalFailed = 0;\n let totalPending = 0;\n let totalCost = 0;\n\n for (const agent of agents) {\n const workers = listWorkersByLeader(agent.id);\n\n const completed = workers.filter((w) => w.status === 'completed').length;\n const failed = workers.filter((w) => w.status === 'failed').length;\n const pending = workers.filter(\n (w) => w.status === 'pending' || w.status === 'running',\n ).length;\n const deptCost = workers.reduce((acc, w) => acc + w.costUsd, 0);\n\n totalCompleted += completed;\n totalFailed += failed;\n totalPending += pending;\n totalCost += deptCost;\n\n if (workers.length > 0) {\n departmentBreakdowns.push({\n department: agent.department,\n leaderId: agent.id,\n leaderRole: agent.role,\n workers: workers.map((w) => ({\n id: w.id,\n taskDescription: w.taskDescription,\n status: w.status,\n costUsd: w.costUsd,\n errorMessage: w.errorMessage,\n })),\n completed,\n failed,\n pending,\n totalCost: deptCost,\n });\n }\n }\n\n const result = {\n meetingId,\n topic: meeting.topic,\n status: meeting.status,\n actionItemCount: minutes?.actionItems.length ?? 0,\n summary: {\n totalWorkers: totalCompleted + totalFailed + totalPending,\n completed: totalCompleted,\n failed: totalFailed,\n pending: totalPending,\n totalCost,\n },\n departments: departmentBreakdowns,\n };\n\n return {\n content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],\n };\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n return {\n content: [\n { type: 'text', text: JSON.stringify({ error: message }, null, 2) },\n ],\n isError: true,\n };\n }\n}\n","import { z } from 'zod';\nimport { ExtensionManager } from '../extension/extension-manager.js';\nimport type { CapabilityType } from '../extension/capability-registry.js';\nimport type { GenerateRequest } from '../extension/generator.js';\n\nexport const createCapabilitySchema = {\n type: z\n .enum(['hook', 'skill', 'command', 'asset', 'loop'])\n .describe('Type of capability to create'),\n name: z.string().describe('Name for the new capability'),\n description: z.string().describe('What the capability does'),\n trigger: z.string().describe('When the capability should be triggered'),\n userRequest: z\n .string()\n .optional()\n .describe('Original user request that triggered creation'),\n};\n\nexport async function createCapabilityHandler({\n type,\n name,\n description,\n trigger,\n userRequest,\n}: {\n type: 'hook' | 'skill' | 'command' | 'asset' | 'loop';\n name: string;\n description: string;\n trigger: string;\n userRequest?: string;\n}): Promise<{ content: { type: 'text'; text: string }[]; isError?: boolean }> {\n try {\n const manager = new ExtensionManager();\n await manager.init();\n\n const request: GenerateRequest = {\n type: type as CapabilityType,\n name,\n description,\n trigger,\n userRequest: userRequest ?? description,\n };\n\n const result = await manager.createCapability(request);\n\n const output = {\n status: 'created',\n capability: {\n type: result.capability.type,\n name: result.capability.name,\n description: result.capability.description,\n trigger: result.capability.trigger,\n isBuiltIn: result.capability.isBuiltIn,\n },\n filePath: result.filePath,\n summary: result.summary,\n };\n\n return {\n content: [{ type: 'text', text: JSON.stringify(output, null, 2) }],\n };\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n return {\n content: [\n { type: 'text', text: JSON.stringify({ error: message }, null, 2) },\n ],\n isError: true,\n };\n }\n}\n","/**\n * capability-registry.ts — Tracks all registered capabilities (built-in + custom).\n *\n * The registry is persisted to ~/.open-coleslaw/registry.json.\n * Built-in capabilities (the 6 hooks + 6 skills that ship with the project) are\n * hardcoded; custom capabilities are added/removed dynamically at runtime.\n */\n\nimport { readFileSync, writeFileSync, existsSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { getConfig } from '../utils/config.js';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport type CapabilityType = 'hook' | 'skill' | 'command' | 'asset' | 'loop';\n\nexport interface Capability {\n type: CapabilityType;\n name: string;\n description: string;\n trigger: string;\n createdAt: number;\n isBuiltIn: boolean;\n filePath: string;\n}\n\n// ---------------------------------------------------------------------------\n// Built-in capability definitions\n// ---------------------------------------------------------------------------\n\nconst BUILT_IN_HOOKS: Omit<Capability, 'createdAt'>[] = [\n {\n type: 'hook',\n name: 'pre-read',\n description: 'Loads rules + plugin guide + CLAUDE.md/README before execution',\n trigger: 'Before every execution',\n isBuiltIn: true,\n filePath: 'src/hooks/pre-read.ts',\n },\n {\n type: 'hook',\n name: 'auto-route',\n description: 'Analyzes user prompts and auto-routes to appropriate skill/agent',\n trigger: 'On every user prompt',\n isBuiltIn: true,\n filePath: 'src/hooks/auto-route.ts',\n },\n {\n type: 'hook',\n name: 'auto-commit',\n description: 'Creates conventional commits after task completion',\n trigger: 'After task completion when git is connected',\n isBuiltIn: true,\n filePath: 'src/hooks/auto-commit.ts',\n },\n {\n type: 'hook',\n name: 'doc-update',\n description: 'Updates CLAUDE.md/README.md after process completion',\n trigger: 'After process completion',\n isBuiltIn: true,\n filePath: 'src/hooks/doc-update.ts',\n },\n {\n type: 'hook',\n name: 'flow-verify',\n description: 'Verifies PRD user flows after development',\n trigger: 'After development phase completes',\n isBuiltIn: true,\n filePath: 'src/hooks/flow-verify.ts',\n },\n {\n type: 'hook',\n name: 'mvp-cycle',\n description: 'Triggers re-meeting on verification failure',\n trigger: 'When flow-verify reports failure',\n isBuiltIn: true,\n filePath: 'src/hooks/mvp-cycle.ts',\n },\n];\n\nconst BUILT_IN_SKILLS: Omit<Capability, 'createdAt'>[] = [\n {\n type: 'skill',\n name: 'meeting',\n description: 'Start a meeting (auto-selects leaders if topic given)',\n trigger: '/meeting [topic]',\n isBuiltIn: true,\n filePath: 'src/skills/meeting.ts',\n },\n {\n type: 'skill',\n name: 'status',\n description: 'Show current meetings, agents, and pending mentions',\n trigger: '/status',\n isBuiltIn: true,\n filePath: 'src/skills/status.ts',\n },\n {\n type: 'skill',\n name: 'dashboard',\n description: 'Open web dashboard at http://localhost:35143',\n trigger: '/dashboard',\n isBuiltIn: true,\n filePath: 'src/skills/dashboard.ts',\n },\n {\n type: 'skill',\n name: 'mention',\n description: 'View and respond to pending @mentions',\n trigger: '/mention',\n isBuiltIn: true,\n filePath: 'src/skills/mention.ts',\n },\n {\n type: 'skill',\n name: 'agents',\n description: 'Show full agent hierarchy tree',\n trigger: '/agents',\n isBuiltIn: true,\n filePath: 'src/skills/agents.ts',\n },\n {\n type: 'skill',\n name: 'minutes',\n description: 'View meeting minutes',\n trigger: '/minutes [meetingId]',\n isBuiltIn: true,\n filePath: 'src/skills/minutes.ts',\n },\n];\n\n// ---------------------------------------------------------------------------\n// Registry class\n// ---------------------------------------------------------------------------\n\nexport class CapabilityRegistry {\n private capabilities: Capability[] = [];\n private registryPath: string;\n\n constructor() {\n const { DATA_DIR } = getConfig();\n this.registryPath = join(DATA_DIR, 'registry.json');\n }\n\n /**\n * Load all capabilities: built-in (hardcoded) + custom (from registry.json).\n */\n async loadAll(): Promise<Capability[]> {\n // Start with built-in capabilities (timestamp 0 — they always existed)\n const builtIns: Capability[] = [\n ...BUILT_IN_HOOKS,\n ...BUILT_IN_SKILLS,\n ].map((cap) => ({ ...cap, createdAt: 0 }));\n\n // Merge in custom capabilities from persistent storage\n const custom = this.readCustomEntries();\n this.capabilities = [...builtIns, ...custom];\n return this.capabilities;\n }\n\n /**\n * Register a new custom capability and persist.\n */\n async register(cap: Omit<Capability, 'createdAt'>): Promise<void> {\n const entry: Capability = { ...cap, createdAt: Date.now() };\n\n // Remove any existing entry with the same name to avoid duplicates\n const custom = this.readCustomEntries().filter((c) => c.name !== cap.name);\n custom.push(entry);\n this.writeCustomEntries(custom);\n\n // Refresh in-memory list\n await this.loadAll();\n }\n\n /**\n * Unregister a custom capability and persist.\n */\n async unregister(type: CapabilityType, name: string): Promise<void> {\n const custom = this.readCustomEntries().filter(\n (c) => !(c.type === type && c.name === name),\n );\n this.writeCustomEntries(custom);\n\n // Refresh in-memory list\n await this.loadAll();\n }\n\n /**\n * Find capabilities by type.\n */\n findByType(type: CapabilityType): Capability[] {\n return this.capabilities.filter((c) => c.type === type);\n }\n\n /**\n * Find a capability by name.\n */\n findByName(name: string): Capability | undefined {\n return this.capabilities.find((c) => c.name === name);\n }\n\n /**\n * Check whether a capability with the given name exists.\n */\n has(name: string): boolean {\n return this.capabilities.some((c) => c.name === name);\n }\n\n /**\n * Format all capabilities as a human-readable list suitable for plugin-guide.md.\n */\n formatForGuide(): string {\n const sections: string[] = [];\n\n const types: CapabilityType[] = ['hook', 'skill', 'command', 'asset', 'loop'];\n for (const type of types) {\n const caps = this.findByType(type);\n if (caps.length === 0) continue;\n\n const label = type.charAt(0).toUpperCase() + type.slice(1) + 's';\n const lines = caps.map((c) => {\n const tag = c.isBuiltIn ? '' : ' [custom]';\n return `- **${c.name}**${tag} — ${c.description} (trigger: ${c.trigger})`;\n });\n sections.push(`### ${label}\\n${lines.join('\\n')}`);\n }\n\n return sections.join('\\n\\n');\n }\n\n // -------------------------------------------------------------------------\n // Private helpers\n // -------------------------------------------------------------------------\n\n private readCustomEntries(): Capability[] {\n if (!existsSync(this.registryPath)) {\n return [];\n }\n try {\n const raw = readFileSync(this.registryPath, 'utf-8');\n const parsed: unknown = JSON.parse(raw);\n if (!Array.isArray(parsed)) return [];\n return parsed as Capability[];\n } catch {\n return [];\n }\n }\n\n private writeCustomEntries(entries: Capability[]): void {\n writeFileSync(this.registryPath, JSON.stringify(entries, null, 2), 'utf-8');\n }\n}\n","import { mkdirSync } from 'node:fs';\nimport { homedir } from 'node:os';\nimport { join } from 'node:path';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport interface AppConfig {\n /** Root data directory: ~/.open-coleslaw/ */\n DATA_DIR: string;\n /** SQLite database path: ~/.open-coleslaw/data.db */\n DB_PATH: string;\n /** Directory for meeting minutes files: ~/.open-coleslaw/minutes/ */\n MINUTES_DIR: string;\n /** WebSocket dashboard port */\n DASHBOARD_PORT: number;\n}\n\n// ---------------------------------------------------------------------------\n// Defaults\n// ---------------------------------------------------------------------------\n\nfunction buildConfig(): AppConfig {\n const DATA_DIR = join(homedir(), '.open-coleslaw');\n return {\n DATA_DIR,\n DB_PATH: join(DATA_DIR, 'data.db'),\n MINUTES_DIR: join(DATA_DIR, 'minutes'),\n DASHBOARD_PORT: 35143,\n };\n}\n\n// Singleton — computed once, reused thereafter.\nlet _config: AppConfig | null = null;\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Return the runtime configuration.\n *\n * Values are derived from well-known paths under `~/.open-coleslaw/`.\n * The config object is created once and cached for the lifetime of the process.\n */\nexport function getConfig(): AppConfig {\n if (!_config) {\n _config = buildConfig();\n }\n return _config;\n}\n\n/**\n * Ensure all required data directories exist (creates them recursively if missing).\n *\n * Call this once during server startup before any storage or file I/O.\n */\nexport function ensureDataDirs(): void {\n const config = getConfig();\n mkdirSync(config.DATA_DIR, { recursive: true });\n mkdirSync(config.MINUTES_DIR, { recursive: true });\n}\n","/**\n * generator.ts — Generates code for new capabilities.\n *\n * Each capability type has a template that produces a standalone file.\n * Generated files are placed in ~/.open-coleslaw/custom-{type}s/.\n */\n\nimport { mkdirSync, writeFileSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { getConfig } from '../utils/config.js';\nimport type { CapabilityType, Capability } from './capability-registry.js';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport interface GenerateRequest {\n type: CapabilityType;\n name: string;\n description: string;\n trigger: string;\n userRequest: string;\n}\n\nexport interface GenerateResult {\n filePath: string;\n code: string;\n registryEntry: Omit<Capability, 'createdAt'>;\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction sanitizeName(name: string): string {\n return name\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, '-')\n .replace(/^-+|-+$/g, '');\n}\n\nfunction header(request: GenerateRequest): string {\n const now = new Date().toISOString();\n return [\n `// Auto-generated by open-coleslaw extension system`,\n `// Name: ${request.name}`,\n `// Description: ${request.description}`,\n `// Trigger: ${request.trigger}`,\n `// Created: ${now}`,\n '',\n ].join('\\n');\n}\n\nfunction customDir(type: CapabilityType): string {\n const { DATA_DIR } = getConfig();\n const dir = join(DATA_DIR, `custom-${type}s`);\n mkdirSync(dir, { recursive: true });\n return dir;\n}\n\n// ---------------------------------------------------------------------------\n// Templates per capability type\n// ---------------------------------------------------------------------------\n\nfunction generateHook(request: GenerateRequest): string {\n return [\n header(request),\n `/**`,\n ` * Custom hook: ${request.name}`,\n ` * ${request.description}`,\n ` *`,\n ` * Trigger: ${request.trigger}`,\n ` * Original request: ${request.userRequest}`,\n ` *`,\n ` * Usage:`,\n ` * node custom-hooks/${sanitizeName(request.name)}.js`,\n ` */`,\n ``,\n `function main() {`,\n ` // Read input from stdin or environment if needed`,\n ` const input = process.env.HOOK_INPUT ?? '';`,\n ``,\n ` // TODO: Implement hook logic for \"${request.description}\"`,\n ` const result = {`,\n ` hook: '${request.name}',`,\n ` status: 'executed',`,\n ` input,`,\n ` timestamp: new Date().toISOString(),`,\n ` };`,\n ``,\n ` process.stdout.write(JSON.stringify(result));`,\n `}`,\n ``,\n `main();`,\n ``,\n ].join('\\n');\n}\n\nfunction generateSkill(request: GenerateRequest): string {\n return [\n header(request),\n `/**`,\n ` * Custom skill: ${request.name}`,\n ` * ${request.description}`,\n ` *`,\n ` * Trigger: ${request.trigger}`,\n ` * Original request: ${request.userRequest}`,\n ` */`,\n ``,\n `export function get${toPascalCase(request.name)}SkillPrompt(args) {`,\n ` const input = args?.trim() ?? '';`,\n ``,\n ` return [`,\n ` '<command-name>${request.name}</command-name>',`,\n ` '',`,\n ` '## ${request.name} Skill',`,\n ` '',`,\n ` '${request.description}',`,\n ` '',`,\n ` input ? \\`User input: \\${input}\\` : 'No input provided.',`,\n ` '',`,\n ` 'Instructions:',`,\n ` '1. Analyze the user request',`,\n ` '2. Perform the action described above',`,\n ` '3. Report the result to the user',`,\n ` ].join('\\\\n');`,\n `}`,\n ``,\n ].join('\\n');\n}\n\nfunction generateCommand(request: GenerateRequest): string {\n return [\n header(request),\n `/**`,\n ` * Custom command: ${request.name}`,\n ` * ${request.description}`,\n ` *`,\n ` * Trigger: ${request.trigger}`,\n ` * Original request: ${request.userRequest}`,\n ` *`,\n ` * Usage:`,\n ` * node custom-commands/${sanitizeName(request.name)}.js [action] [args...]`,\n ` */`,\n ``,\n `function main() {`,\n ` const args = process.argv.slice(2);`,\n ` const action = args[0] ?? 'default';`,\n ` const rest = args.slice(1);`,\n ``,\n ` const handlers = {`,\n ` default: () => ({`,\n ` command: '${request.name}',`,\n ` description: '${request.description}',`,\n ` usage: '${request.name}:action [args]',`,\n ` }),`,\n ` run: () => {`,\n ` // TODO: Implement the primary command action`,\n ` return {`,\n ` command: '${request.name}',`,\n ` action: 'run',`,\n ` args: rest,`,\n ` status: 'executed',`,\n ` timestamp: new Date().toISOString(),`,\n ` };`,\n ` },`,\n ` };`,\n ``,\n ` const handler = handlers[action] ?? handlers.default;`,\n ` const result = handler();`,\n ` process.stdout.write(JSON.stringify(result, null, 2));`,\n `}`,\n ``,\n `main();`,\n ``,\n ].join('\\n');\n}\n\nfunction generateAsset(request: GenerateRequest): string {\n // Assets can be JSON or Markdown. Default to JSON for configs, Markdown for docs.\n const isMarkdown =\n /template|guide|doc|readme|note/i.test(request.name) ||\n /template|guide|doc|readme|note/i.test(request.description);\n\n if (isMarkdown) {\n return [\n `<!-- Auto-generated by open-coleslaw extension system -->`,\n `<!-- Name: ${request.name} -->`,\n `<!-- Description: ${request.description} -->`,\n `<!-- Trigger: ${request.trigger} -->`,\n `<!-- Created: ${new Date().toISOString()} -->`,\n ``,\n `# ${request.name}`,\n ``,\n `${request.description}`,\n ``,\n `## Details`,\n ``,\n `> Original request: ${request.userRequest}`,\n ``,\n `<!-- TODO: Fill in content -->`,\n ``,\n ].join('\\n');\n }\n\n const data = {\n _meta: {\n generatedBy: 'open-coleslaw extension system',\n name: request.name,\n description: request.description,\n trigger: request.trigger,\n created: new Date().toISOString(),\n userRequest: request.userRequest,\n },\n config: {},\n };\n\n return JSON.stringify(data, null, 2) + '\\n';\n}\n\nfunction generateLoop(request: GenerateRequest): string {\n return [\n header(request),\n `/**`,\n ` * Custom loop: ${request.name}`,\n ` * ${request.description}`,\n ` *`,\n ` * Trigger: ${request.trigger}`,\n ` * Original request: ${request.userRequest}`,\n ` *`,\n ` * Usage:`,\n ` * node custom-loops/${sanitizeName(request.name)}.js`,\n ` */`,\n ``,\n `const INTERVAL_MS = 30000; // 30 seconds`,\n `const MAX_ITERATIONS = 100;`,\n ``,\n `async function check() {`,\n ` // TODO: Implement the condition check for \"${request.description}\"`,\n ` const result = {`,\n ` loop: '${request.name}',`,\n ` iteration: 0,`,\n ` timestamp: new Date().toISOString(),`,\n ` conditionMet: false,`,\n ` };`,\n ` return result;`,\n `}`,\n ``,\n `async function main() {`,\n ` let iteration = 0;`,\n ``,\n ` while (iteration < MAX_ITERATIONS) {`,\n ` iteration++;`,\n ` const result = await check();`,\n ` result.iteration = iteration;`,\n ``,\n ` process.stdout.write(JSON.stringify(result) + '\\\\n');`,\n ``,\n ` if (result.conditionMet) {`,\n ` process.stdout.write(JSON.stringify({`,\n ` loop: '${request.name}',`,\n ` status: 'completed',`,\n ` totalIterations: iteration,`,\n ` }) + '\\\\n');`,\n ` break;`,\n ` }`,\n ``,\n ` await new Promise((resolve) => setTimeout(resolve, INTERVAL_MS));`,\n ` }`,\n `}`,\n ``,\n `main().catch((err) => {`,\n ` process.stderr.write(String(err));`,\n ` process.exit(1);`,\n `});`,\n ``,\n ].join('\\n');\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction toPascalCase(str: string): string {\n return str\n .split(/[-_\\s]+/)\n .map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())\n .join('');\n}\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Generate code for a new capability.\n *\n * Returns the file path where the code was written, the code itself,\n * and the registry entry to persist.\n */\nexport function generateCapability(request: GenerateRequest): GenerateResult {\n const safeName = sanitizeName(request.name);\n\n // Determine file extension based on type\n const isAssetMarkdown =\n request.type === 'asset' &&\n (/template|guide|doc|readme|note/i.test(request.name) ||\n /template|guide|doc|readme|note/i.test(request.description));\n\n let ext: string;\n if (request.type === 'asset') {\n ext = isAssetMarkdown ? '.md' : '.json';\n } else {\n ext = '.js';\n }\n\n const dir = customDir(request.type);\n const filePath = join(dir, `${safeName}${ext}`);\n\n // Generate the code\n let code: string;\n switch (request.type) {\n case 'hook':\n code = generateHook(request);\n break;\n case 'skill':\n code = generateSkill(request);\n break;\n case 'command':\n code = generateCommand(request);\n break;\n case 'asset':\n code = generateAsset(request);\n break;\n case 'loop':\n code = generateLoop(request);\n break;\n }\n\n // Write the file\n writeFileSync(filePath, code, 'utf-8');\n\n return {\n filePath,\n code,\n registryEntry: {\n type: request.type,\n name: request.name,\n description: request.description,\n trigger: request.trigger,\n isBuiltIn: false,\n filePath,\n },\n };\n}\n","/**\n * guide-updater.ts — Updates plugin-guide.md and rules.md when capabilities change.\n *\n * Regenerates plugin-guide.md with the current set of capabilities.\n * For rules.md, only appends custom rules — never removes base rules.\n */\n\nimport { readFileSync, writeFileSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { getConfig } from '../utils/config.js';\nimport type { CapabilityRegistry } from './capability-registry.js';\n\n// ---------------------------------------------------------------------------\n// Plugin guide\n// ---------------------------------------------------------------------------\n\n/**\n * Regenerate plugin-guide.md with the current set of registered capabilities.\n *\n * The guide is written to ~/.open-coleslaw/plugin-guide.md where the pre-read\n * hook picks it up.\n */\nexport async function updatePluginGuide(\n registry: CapabilityRegistry,\n): Promise<void> {\n const { DATA_DIR } = getConfig();\n const guidePath = join(DATA_DIR, 'plugin-guide.md');\n\n const capSection = registry.formatForGuide();\n\n const guide = [\n '# Open-Coleslaw Plugin Guide',\n '',\n '## Overview',\n 'Multi-agent orchestrator for Claude Code. Hierarchical agent system:',\n 'Orchestrator (proxy) -> Part Leaders (team leads) -> Workers (executors)',\n '',\n '## Registered Capabilities',\n '',\n capSection,\n '',\n '## Agent Tiers',\n '| Tier | Model | Role |',\n '|------|-------|------|',\n '| Orchestrator | claude-opus-4-6 (1M) | Full-picture routing, delegation |',\n '| Leader | claude-sonnet-4-6 | Meetings, technical decisions |',\n '| Worker (impl) | claude-sonnet-4-6 | Code, implementation |',\n '| Worker (research) | claude-haiku-4-5 | Quick lookups |',\n '',\n '## Departments',\n '- Architecture: system design, API, schema',\n '- Engineering: implementation, code quality',\n '- QA: testing, security, performance',\n '- Product: requirements, user stories',\n '- Research: codebase exploration, docs',\n '',\n '## Meeting Minutes',\n 'Saved to: ~/.open-coleslaw/minutes/',\n 'Index: ~/.open-coleslaw/minutes/INDEX.md',\n 'Format: PRD with frontmatter metadata + tags',\n '',\n '## Extension System',\n 'Custom capabilities are stored in ~/.open-coleslaw/custom-{type}s/.',\n 'Use the `create-capability` MCP tool to add new hooks, skills, commands, assets, or loops.',\n 'Registry: ~/.open-coleslaw/registry.json',\n '',\n ].join('\\n');\n\n writeFileSync(guidePath, guide, 'utf-8');\n}\n\n// ---------------------------------------------------------------------------\n// Rules\n// ---------------------------------------------------------------------------\n\n/** Sentinel that marks the beginning of the custom-rules block. */\nconst CUSTOM_RULES_START = '## Custom Rules';\nconst CUSTOM_RULES_END = '<!-- /custom-rules -->';\n\n/**\n * Append custom rules to rules.md without removing any base rules.\n *\n * Custom rules are bracketed between a `## Custom Rules` heading and\n * a closing HTML comment so they can be cleanly replaced on subsequent calls.\n */\nexport async function updateRulesIfNeeded(\n customRules: string[],\n): Promise<void> {\n if (customRules.length === 0) return;\n\n const { DATA_DIR } = getConfig();\n const rulesPath = join(DATA_DIR, 'rules.md');\n\n let existing: string;\n try {\n existing = readFileSync(rulesPath, 'utf-8');\n } catch {\n // If no rules.md yet, start from an empty document\n existing = '';\n }\n\n // Strip any previous custom-rules block\n const startIdx = existing.indexOf(CUSTOM_RULES_START);\n const endIdx = existing.indexOf(CUSTOM_RULES_END);\n let base: string;\n if (startIdx !== -1 && endIdx !== -1) {\n base =\n existing.slice(0, startIdx).trimEnd() +\n '\\n' +\n existing.slice(endIdx + CUSTOM_RULES_END.length).trimStart();\n } else if (startIdx !== -1) {\n base = existing.slice(0, startIdx).trimEnd();\n } else {\n base = existing;\n }\n\n // Build the new custom-rules section\n const rulesBlock = [\n '',\n CUSTOM_RULES_START,\n ...customRules.map((r) => `- ${r}`),\n CUSTOM_RULES_END,\n ].join('\\n');\n\n const updated = base.trimEnd() + '\\n' + rulesBlock + '\\n';\n writeFileSync(rulesPath, updated, 'utf-8');\n}\n","/**\n * extension-manager.ts — Top-level orchestrator for the extension system.\n *\n * Coordinates the CapabilityRegistry, code generator, and guide updater\n * so that the rest of the system has a single entry-point for extension\n * operations.\n */\n\nimport { CapabilityRegistry } from './capability-registry.js';\nimport type {\n CapabilityType,\n Capability,\n} from './capability-registry.js';\nimport { generateCapability } from './generator.js';\nimport type { GenerateRequest } from './generator.js';\nimport { updatePluginGuide } from './guide-updater.js';\n\n// ---------------------------------------------------------------------------\n// Analysis result\n// ---------------------------------------------------------------------------\n\nexport interface AnalysisResult {\n needsNewCapability: boolean;\n suggestedType?: CapabilityType;\n suggestedName?: string;\n suggestedDescription?: string;\n suggestedTrigger?: string;\n}\n\n// ---------------------------------------------------------------------------\n// Creation result\n// ---------------------------------------------------------------------------\n\nexport interface CreateResult {\n capability: Capability;\n filePath: string;\n summary: string;\n}\n\n// ---------------------------------------------------------------------------\n// Keyword patterns for request analysis\n// ---------------------------------------------------------------------------\n\ninterface KeywordRule {\n type: CapabilityType;\n patterns: RegExp[];\n}\n\nconst KEYWORD_RULES: KeywordRule[] = [\n {\n type: 'hook',\n patterns: [\n /\\bevery\\s+time\\b/i,\n /\\balways\\b/i,\n /\\bbefore\\s+\\w+/i,\n /\\bafter\\s+\\w+/i,\n /\\bwhen\\s+\\w+/i,\n /\\bon\\s+(every|each)\\b/i,\n ],\n },\n {\n type: 'skill',\n patterns: [\n /\\/\\w+/,\n /\\bslash\\s+command\\b/i,\n /\\bshortcut\\b/i,\n /\\bskill\\b/i,\n ],\n },\n {\n type: 'asset',\n patterns: [\n /\\btemplate\\b/i,\n /\\bconfig\\b/i,\n /\\bsettings\\b/i,\n /\\bconfiguration\\b/i,\n ],\n },\n {\n type: 'loop',\n patterns: [\n /\\bcheck\\s+every\\b/i,\n /\\bpoll\\b/i,\n /\\bwatch\\b/i,\n /\\bmonitor\\b/i,\n /\\brepeatedly\\b/i,\n /\\bperiodically\\b/i,\n ],\n },\n];\n\n// ---------------------------------------------------------------------------\n// ExtensionManager\n// ---------------------------------------------------------------------------\n\nexport class ExtensionManager {\n private registry: CapabilityRegistry;\n\n constructor() {\n this.registry = new CapabilityRegistry();\n }\n\n /**\n * Initialize: load the registry from disk.\n */\n async init(): Promise<void> {\n await this.registry.loadAll();\n }\n\n /**\n * Analyze a user request to decide whether a new capability is needed.\n *\n * Uses keyword matching to suggest the capability type. Returns\n * `needsNewCapability: false` when the request matches an existing\n * capability name.\n */\n async analyzeRequest(request: string): Promise<AnalysisResult> {\n // If a capability with a matching name already exists, no creation needed\n const normalized = request.toLowerCase().trim();\n\n for (const cap of await this.registry.loadAll()) {\n if (normalized.includes(cap.name.toLowerCase())) {\n return { needsNewCapability: false };\n }\n }\n\n // Try to match keyword rules\n for (const rule of KEYWORD_RULES) {\n for (const pattern of rule.patterns) {\n if (pattern.test(request)) {\n const nameCandidate = extractName(request);\n return {\n needsNewCapability: true,\n suggestedType: rule.type,\n suggestedName: nameCandidate,\n suggestedDescription: request.slice(0, 120),\n suggestedTrigger: extractTrigger(request, rule.type),\n };\n }\n }\n }\n\n // Default: treat as a generic command\n return {\n needsNewCapability: true,\n suggestedType: 'command',\n suggestedName: extractName(request),\n suggestedDescription: request.slice(0, 120),\n suggestedTrigger: 'On user invocation',\n };\n }\n\n /**\n * Create a new capability, persist it, and update the plugin guide.\n */\n async createCapability(request: GenerateRequest): Promise<CreateResult> {\n // Generate the code file\n const result = generateCapability(request);\n\n // Register in the capability registry\n await this.registry.register(result.registryEntry);\n\n // Refresh the plugin guide so pre-read picks it up\n await updatePluginGuide(this.registry);\n\n // Build the full Capability object to return\n const capability: Capability = {\n ...result.registryEntry,\n createdAt: Date.now(),\n };\n\n const summary =\n `Created ${request.type} \"${request.name}\": ${request.description}. ` +\n `File: ${result.filePath}`;\n\n return { capability, filePath: result.filePath, summary };\n }\n\n /**\n * List all capabilities (built-in + custom).\n */\n async listCapabilities(): Promise<Capability[]> {\n return this.registry.loadAll();\n }\n\n /**\n * Remove a custom capability by name.\n *\n * Built-in capabilities cannot be removed.\n */\n async removeCapability(name: string): Promise<void> {\n const cap = this.registry.findByName(name);\n if (!cap) {\n throw new Error(`Capability not found: ${name}`);\n }\n if (cap.isBuiltIn) {\n throw new Error(`Cannot remove built-in capability: ${name}`);\n }\n\n await this.registry.unregister(cap.type, name);\n\n // Refresh the plugin guide\n await updatePluginGuide(this.registry);\n }\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Extract a reasonable short name from a user request string.\n */\nfunction extractName(request: string): string {\n // Try to pull out a slash-command name like /foo\n const slashMatch = request.match(/\\/(\\w[\\w-]*)/);\n if (slashMatch) return slashMatch[1];\n\n // Otherwise, take the first few meaningful words\n const words = request\n .replace(/[^a-zA-Z0-9\\s-]/g, '')\n .split(/\\s+/)\n .filter((w) => w.length > 2)\n .slice(0, 3);\n\n return words.join('-').toLowerCase() || 'unnamed';\n}\n\n/**\n * Generate a trigger description from the request and inferred type.\n */\nfunction extractTrigger(request: string, type: CapabilityType): string {\n switch (type) {\n case 'hook': {\n const beforeMatch = request.match(/before\\s+(\\w[\\w\\s]{0,30})/i);\n if (beforeMatch) return `Before ${beforeMatch[1].trim()}`;\n const afterMatch = request.match(/after\\s+(\\w[\\w\\s]{0,30})/i);\n if (afterMatch) return `After ${afterMatch[1].trim()}`;\n const whenMatch = request.match(/when\\s+(\\w[\\w\\s]{0,30})/i);\n if (whenMatch) return `When ${whenMatch[1].trim()}`;\n return 'On configured trigger';\n }\n case 'skill':\n return `/${extractName(request)}`;\n case 'loop': {\n const everyMatch = request.match(/every\\s+([\\w\\s]+)/i);\n if (everyMatch) return `Every ${everyMatch[1].trim()}`;\n return 'On interval';\n }\n case 'asset':\n return 'When referenced';\n case 'command':\n return 'On user invocation';\n }\n}\n","import { z } from 'zod';\nimport { costTracker } from '../utils/cost-tracker.js';\n\nexport const getCostSummarySchema = {\n meetingId: z.string().optional().describe('Optional meeting ID to filter costs'),\n};\n\nexport async function getCostSummaryHandler({\n meetingId,\n}: {\n meetingId?: string;\n}): Promise<{ content: { type: 'text'; text: string }[]; isError?: boolean }> {\n try {\n const summary = costTracker.getSummary(meetingId);\n const budgetWarning = costTracker.checkBudget();\n\n const result: Record<string, unknown> = {\n ...summary,\n };\n\n if (budgetWarning) {\n result.budgetWarning = budgetWarning;\n }\n\n if (meetingId) {\n result.filteredByMeeting = meetingId;\n }\n\n return {\n content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],\n };\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n return {\n content: [\n { type: 'text', text: JSON.stringify({ error: message }, null, 2) },\n ],\n isError: true,\n };\n }\n}\n","import { getDb } from '../storage/db.js';\n\n// ---------------------------------------------------------------------------\n// Cost summary\n// ---------------------------------------------------------------------------\n\nexport interface CostSummary {\n totalUsd: number;\n byMeeting: Record<string, number>;\n byDepartment: Record<string, number>;\n byTier: Record<string, number>;\n budgetLimit: number | null;\n budgetRemaining: number | null;\n}\n\n// ---------------------------------------------------------------------------\n// In-memory cost entry\n// ---------------------------------------------------------------------------\n\ninterface CostEntry {\n agentId: string;\n meetingId: string;\n costUsd: number;\n recordedAt: number;\n}\n\n// ---------------------------------------------------------------------------\n// CostTracker\n// ---------------------------------------------------------------------------\n\nexport class CostTracker {\n private budgetLimitUsd: number | null = null;\n private entries: CostEntry[] = [];\n\n /** Set a budget limit in USD. */\n setBudget(limitUsd: number): void {\n this.budgetLimitUsd = limitUsd;\n }\n\n /** Record a cost for an agent action. */\n recordCost(agentId: string, meetingId: string, costUsd: number): void {\n this.entries.push({\n agentId,\n meetingId,\n costUsd,\n recordedAt: Date.now(),\n });\n }\n\n /** Get the current cost summary, combining in-memory entries with DB data. */\n getSummary(meetingId?: string): CostSummary {\n const byMeeting: Record<string, number> = {};\n const byDepartment: Record<string, number> = {};\n const byTier: Record<string, number> = {};\n let totalUsd = 0;\n\n // 1. Aggregate from the agents table in the DB\n try {\n const db = getDb();\n\n interface AgentCostRow {\n meeting_id: string | null;\n department: string;\n tier: string;\n cost_usd: number;\n }\n\n let agentRows: AgentCostRow[];\n if (meetingId) {\n agentRows = db\n .prepare('SELECT meeting_id, department, tier, cost_usd FROM agents WHERE meeting_id = ?')\n .all(meetingId) as AgentCostRow[];\n } else {\n agentRows = db\n .prepare('SELECT meeting_id, department, tier, cost_usd FROM agents')\n .all() as AgentCostRow[];\n }\n\n for (const row of agentRows) {\n const cost = row.cost_usd ?? 0;\n if (cost === 0) continue;\n\n totalUsd += cost;\n const mid = row.meeting_id ?? 'unknown';\n byMeeting[mid] = (byMeeting[mid] ?? 0) + cost;\n byDepartment[row.department] = (byDepartment[row.department] ?? 0) + cost;\n byTier[row.tier] = (byTier[row.tier] ?? 0) + cost;\n }\n\n // 2. Aggregate from the workers table\n interface WorkerCostRow {\n meeting_id: string;\n cost_usd: number;\n leader_id: string;\n }\n\n let workerRows: WorkerCostRow[];\n if (meetingId) {\n workerRows = db\n .prepare('SELECT meeting_id, cost_usd, leader_id FROM workers WHERE meeting_id = ?')\n .all(meetingId) as WorkerCostRow[];\n } else {\n workerRows = db\n .prepare('SELECT meeting_id, cost_usd, leader_id FROM workers')\n .all() as WorkerCostRow[];\n }\n\n for (const row of workerRows) {\n const cost = row.cost_usd ?? 0;\n if (cost === 0) continue;\n\n totalUsd += cost;\n byMeeting[row.meeting_id] = (byMeeting[row.meeting_id] ?? 0) + cost;\n byTier['worker'] = (byTier['worker'] ?? 0) + cost;\n\n // Look up the leader's department for the worker\n interface LeaderDeptRow { department: string }\n const leader = db\n .prepare('SELECT department FROM agents WHERE id = ?')\n .get(row.leader_id) as LeaderDeptRow | undefined;\n if (leader) {\n byDepartment[leader.department] = (byDepartment[leader.department] ?? 0) + cost;\n }\n }\n } catch {\n // DB might not be initialised yet; fall through to in-memory only\n }\n\n // 3. Aggregate in-memory entries\n const filteredEntries = meetingId\n ? this.entries.filter((e) => e.meetingId === meetingId)\n : this.entries;\n\n for (const entry of filteredEntries) {\n totalUsd += entry.costUsd;\n byMeeting[entry.meetingId] = (byMeeting[entry.meetingId] ?? 0) + entry.costUsd;\n }\n\n return {\n totalUsd,\n byMeeting,\n byDepartment,\n byTier,\n budgetLimit: this.budgetLimitUsd,\n budgetRemaining: this.budgetLimitUsd !== null ? this.budgetLimitUsd - totalUsd : null,\n };\n }\n\n /** Check if over budget. Returns a warning message or null. */\n checkBudget(): string | null {\n if (this.budgetLimitUsd === null) return null;\n\n const summary = this.getSummary();\n if (summary.totalUsd >= this.budgetLimitUsd) {\n return `Budget exceeded: $${summary.totalUsd.toFixed(4)} spent of $${this.budgetLimitUsd.toFixed(4)} limit`;\n }\n\n const remaining = this.budgetLimitUsd - summary.totalUsd;\n if (remaining < this.budgetLimitUsd * 0.1) {\n return `Budget warning: $${summary.totalUsd.toFixed(4)} spent, only $${remaining.toFixed(4)} remaining of $${this.budgetLimitUsd.toFixed(4)} limit`;\n }\n\n return null;\n }\n}\n\n/** Shared singleton instance. */\nexport const costTracker = new CostTracker();\n","import { z } from 'zod';\nimport { Orchestrator } from '../orchestrator/orchestrator.js';\nimport type { Department } from '../types/index.js';\n\nexport const chainMeetingSchema = {\n previousMeetingId: z.string().describe('ID of the previous meeting to chain from'),\n topic: z.string().describe('Topic for the new chained meeting'),\n agenda: z.array(z.string()).describe('Agenda items for the new meeting'),\n departments: z\n .array(z.string())\n .optional()\n .describe('Specific departments to invite'),\n};\n\nexport async function chainMeetingHandler({\n previousMeetingId,\n topic,\n agenda,\n departments,\n}: {\n previousMeetingId: string;\n topic: string;\n agenda: string[];\n departments?: string[];\n}): Promise<{ content: { type: 'text'; text: string }[]; isError?: boolean }> {\n try {\n const orchestrator = new Orchestrator();\n const meetingId = await orchestrator.chainMeeting({\n previousMeetingId,\n topic,\n agenda,\n departments: departments as Department[] | undefined,\n });\n\n const result = {\n meetingId,\n status: 'started',\n chainedFrom: previousMeetingId,\n topic,\n agenda,\n departments: departments ?? orchestrator.selectLeaders(topic, agenda),\n };\n\n return {\n content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],\n };\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n return {\n content: [\n { type: 'text', text: JSON.stringify({ error: message }, null, 2) },\n ],\n isError: true,\n };\n }\n}\n","import { createServer as createHttpServer } from 'node:http';\nimport { WebSocketServer, WebSocket } from 'ws';\nimport { getDashboardHTML } from './html.js';\nimport { StateBridge } from './state-bridge.js';\nimport { DashboardClient } from './client.js';\nimport { eventBus } from '../orchestrator/event-bus.js';\nimport { getConfig } from '../utils/config.js';\nimport { logger } from '../utils/logger.js';\nimport type { AgentEvent, ServerMessage } from '../types/dashboard-events.js';\n\nexport interface DashboardHandle {\n isOwner: boolean;\n close: () => void;\n}\n\nexport interface DashboardOptions {\n sessionId: string;\n projectPath: string;\n projectName: string;\n}\n\nexport function startDashboard(options: DashboardOptions): Promise<DashboardHandle> {\n const port = getConfig().DASHBOARD_PORT;\n\n return new Promise((resolve) => {\n const httpServer = createHttpServer((req, res) => {\n if (req.url === '/' || req.url === '/index.html') {\n res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' });\n res.end(getDashboardHTML());\n } else {\n res.writeHead(404);\n res.end('Not Found');\n }\n });\n\n httpServer.on('error', (err: NodeJS.ErrnoException) => {\n if (err.code === 'EADDRINUSE') {\n // Port in use — become a client\n logger.info(`Dashboard port ${port} in use — connecting as client`);\n const client = new DashboardClient(options.sessionId, options.projectName, options.projectPath);\n client.connect(port);\n resolve({\n isOwner: false,\n close: () => client.disconnect(),\n });\n } else {\n logger.error(`Dashboard error: ${err.message}`);\n resolve({ isOwner: false, close: () => {} });\n }\n });\n\n httpServer.listen(port, '127.0.0.1', () => {\n logger.info(`Dashboard owner — running at http://localhost:${port}`);\n\n const wss = new WebSocketServer({ server: httpServer });\n const bridge = new StateBridge();\n\n // Register own session\n const displayName = bridge.registerSession({\n sessionId: options.sessionId,\n projectPath: options.projectPath,\n projectName: options.projectName,\n });\n logger.info(`Registered own session: ${displayName}`);\n\n // Forward local events to bridge\n eventBus.on('agent_event', (event: AgentEvent) => {\n bridge.handleSessionEvent(options.sessionId, event);\n });\n\n // Handle browser clients + MCP server clients\n wss.on('connection', (ws: WebSocket) => {\n // Send full snapshot\n ws.send(JSON.stringify(bridge.getSnapshot()));\n\n ws.on('message', (data: Buffer) => {\n try {\n const msg: ServerMessage = JSON.parse(data.toString());\n\n if (msg.type === 'register') {\n const name = bridge.registerSession({\n sessionId: msg.sessionId,\n projectPath: msg.projectPath,\n projectName: msg.projectName,\n });\n // Notify all browser clients\n const notification = JSON.stringify({\n type: 'session-registered',\n sessionId: msg.sessionId,\n displayName: name,\n projectPath: msg.projectPath,\n });\n wss.clients.forEach((c) => {\n if (c !== ws && c.readyState === WebSocket.OPEN) c.send(notification);\n });\n } else if (msg.type === 'session-event') {\n bridge.handleSessionEvent(msg.sessionId, msg.event);\n } else if (msg.type === 'unregister') {\n bridge.unregisterSession(msg.sessionId);\n const notification = JSON.stringify({\n type: 'session-unregistered',\n sessionId: msg.sessionId,\n });\n wss.clients.forEach((c) => {\n if (c.readyState === WebSocket.OPEN) c.send(notification);\n });\n } else if ((msg as any).type === 'ping') {\n ws.send(JSON.stringify({ type: 'pong' }));\n }\n } catch {\n // ignore malformed\n }\n });\n });\n\n // Broadcast deltas to all browser clients\n bridge.on('broadcast', (data: string) => {\n wss.clients.forEach((c) => {\n if (c.readyState === WebSocket.OPEN) c.send(data);\n });\n });\n\n resolve({\n isOwner: true,\n close: () => {\n bridge.unregisterSession(options.sessionId);\n wss.close();\n httpServer.close();\n },\n });\n });\n });\n}\n","/**\n * getDashboardHTML() — returns the full inline HTML/CSS/JS for the Open Coleslaw\n * real-time dashboard. Everything is self-contained; the only external deps are\n * Cytoscape.js + dagre loaded from CDN.\n *\n * Multi-session aware: one tab per project session in the tab bar.\n */\n\nexport function getDashboardHTML(): string {\n return /* html */ `<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n<meta charset=\"utf-8\" />\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" />\n<title>Open Coleslaw Dashboard</title>\n\n<!-- CDN deps -->\n<script src=\"https://cdnjs.cloudflare.com/ajax/libs/cytoscape/3.30.4/cytoscape.min.js\"></script>\n<script src=\"https://cdnjs.cloudflare.com/ajax/libs/dagre/0.8.5/dagre.min.js\"></script>\n<script src=\"https://unpkg.com/cytoscape-dagre@2.5.0/cytoscape-dagre.js\"></script>\n\n<!-- Google Fonts: JetBrains Mono -->\n<link rel=\"preconnect\" href=\"https://fonts.googleapis.com\" />\n<link rel=\"preconnect\" href=\"https://fonts.gstatic.com\" crossorigin />\n<link href=\"https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@300;400;500;600;700&display=swap\" rel=\"stylesheet\" />\n\n<style>\n/* ===================================================================\n RESET & VARIABLES\n =================================================================== */\n*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }\n\n:root {\n --bg: #0a0e17;\n --surface: #111827;\n --border: #1e293b;\n --cyan: #00f0ff;\n --purple: #a855f7;\n --lightcyan: #22d3ee;\n --success: #10b981;\n --warning: #f59e0b;\n --error: #ef4444;\n --text: #e2e8f0;\n --text2: #94a3b8;\n --font: 'JetBrains Mono', 'Fira Code', monospace;\n}\n\nhtml, body {\n width: 100%; height: 100%;\n overflow: hidden;\n background: var(--bg);\n color: var(--text);\n font-family: var(--font);\n font-size: 13px;\n line-height: 1.5;\n}\n\n/* ===================================================================\n LAYOUT — five areas via CSS Grid\n =================================================================== */\n#app {\n display: grid;\n width: 100%; height: 100%;\n grid-template-rows: 48px 36px 1fr 200px;\n grid-template-columns: 1fr 320px;\n grid-template-areas:\n \"header header\"\n \"tabs tabs\"\n \"graph sidebar\"\n \"log log\";\n}\n\n/* ===================================================================\n HEADER\n =================================================================== */\n#header {\n grid-area: header;\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 0 20px;\n background: var(--surface);\n border-bottom: 1px solid var(--border);\n gap: 16px;\n z-index: 10;\n}\n\n#header .brand {\n display: flex;\n align-items: center;\n gap: 10px;\n font-size: 16px;\n font-weight: 700;\n color: var(--cyan);\n text-shadow: 0 0 12px rgba(0,240,255,0.5);\n white-space: nowrap;\n}\n\n#header .center-status {\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 12px;\n}\n\n.conn-dot {\n width: 10px; height: 10px;\n border-radius: 50%;\n background: var(--error);\n transition: background 0.3s;\n box-shadow: 0 0 6px rgba(239,68,68,0.6);\n}\n.conn-dot.connected {\n background: var(--success);\n box-shadow: 0 0 6px rgba(16,185,129,0.6);\n}\n.conn-dot.reconnecting {\n background: var(--warning);\n box-shadow: 0 0 6px rgba(245,158,11,0.6);\n animation: breathe 1.5s ease-in-out infinite;\n}\n\n#header .right-stats {\n display: flex;\n align-items: center;\n gap: 14px;\n font-size: 12px;\n}\n\n.badge {\n background: rgba(0,240,255,0.1);\n border: 1px solid rgba(0,240,255,0.25);\n padding: 2px 10px;\n border-radius: 12px;\n font-size: 11px;\n white-space: nowrap;\n}\n.badge.purple { background: rgba(168,85,247,0.1); border-color: rgba(168,85,247,0.3); }\n.badge.amber { background: rgba(245,158,11,0.1); border-color: rgba(245,158,11,0.3); color: var(--warning); }\n.badge.green { background: rgba(16,185,129,0.1); border-color: rgba(16,185,129,0.3); color: var(--success); }\n\n/* ===================================================================\n TAB BAR\n =================================================================== */\n#tab-bar {\n grid-area: tabs;\n display: flex;\n align-items: stretch;\n background: var(--surface);\n border-bottom: 1px solid var(--border);\n padding: 0 12px;\n gap: 2px;\n overflow-x: auto;\n overflow-y: hidden;\n scrollbar-width: none;\n}\n#tab-bar::-webkit-scrollbar { display: none; }\n\n.session-tab {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 0 14px;\n font-size: 11px;\n font-family: var(--font);\n font-weight: 500;\n color: var(--text2);\n background: transparent;\n border: none;\n border-bottom: 2px solid transparent;\n cursor: pointer;\n white-space: nowrap;\n transition: color 0.2s, border-color 0.2s, opacity 0.2s;\n position: relative;\n}\n.session-tab:hover {\n color: var(--text);\n background: rgba(255,255,255,0.02);\n}\n.session-tab.active {\n color: var(--cyan);\n border-bottom-color: var(--cyan);\n text-shadow: 0 0 8px rgba(0,240,255,0.4);\n}\n.session-tab.inactive {\n opacity: 0.45;\n text-decoration: line-through;\n color: var(--text2);\n}\n.session-tab.inactive:hover {\n opacity: 0.6;\n}\n\n.tab-badge {\n font-size: 9px;\n padding: 1px 5px;\n border-radius: 8px;\n background: rgba(0,240,255,0.15);\n color: var(--cyan);\n font-weight: 700;\n min-width: 16px;\n text-align: center;\n}\n.tab-badge.meeting {\n background: rgba(245,158,11,0.2);\n color: var(--warning);\n}\n\n.tab-empty-msg {\n display: flex;\n align-items: center;\n font-size: 11px;\n color: var(--text2);\n font-style: italic;\n padding: 0 8px;\n}\n\n/* ===================================================================\n GRAPH VIEWPORT\n =================================================================== */\n#graph-container {\n grid-area: graph;\n background: var(--bg);\n position: relative;\n overflow: hidden;\n}\n#cy {\n width: 100%; height: 100%;\n}\n/* watermark text */\n#graph-container::after {\n content: 'AGENT GRAPH';\n position: absolute;\n bottom: 12px; left: 16px;\n font-size: 10px;\n color: rgba(148,163,184,0.25);\n letter-spacing: 3px;\n pointer-events: none;\n}\n\n/* ===================================================================\n SIDEBAR\n =================================================================== */\n#sidebar {\n grid-area: sidebar;\n background: var(--surface);\n border-left: 1px solid var(--border);\n padding: 16px;\n overflow-y: auto;\n display: flex;\n flex-direction: column;\n gap: 12px;\n}\n\n#sidebar h2 {\n font-size: 12px;\n text-transform: uppercase;\n letter-spacing: 2px;\n color: var(--text2);\n margin-bottom: 4px;\n}\n\n.sidebar-empty {\n color: var(--text2);\n font-style: italic;\n font-size: 12px;\n margin-top: 40px;\n text-align: center;\n}\n\n.detail-row {\n display: flex;\n justify-content: space-between;\n padding: 4px 0;\n border-bottom: 1px solid var(--border);\n font-size: 12px;\n}\n.detail-row .label { color: var(--text2); }\n.detail-row .value { color: var(--text); font-weight: 500; }\n\n.status-chip {\n display: inline-block;\n padding: 1px 8px;\n border-radius: 6px;\n font-size: 11px;\n font-weight: 600;\n}\n.status-chip.idle { background: rgba(148,163,184,0.15); color: var(--text2); }\n.status-chip.working { background: rgba(0,240,255,0.15); color: var(--cyan); }\n.status-chip.in-meeting { background: rgba(245,158,11,0.15); color: var(--warning); }\n.status-chip.spawning-workers { background: rgba(168,85,247,0.15); color: var(--purple); }\n.status-chip.aggregating { background: rgba(34,211,238,0.15); color: var(--lightcyan); }\n.status-chip.waiting-for-user { background: rgba(245,158,11,0.15); color: var(--warning); }\n.status-chip.completed { background: rgba(16,185,129,0.15); color: var(--success); }\n.status-chip.failed { background: rgba(239,68,68,0.15); color: var(--error); }\n\n.task-block {\n background: rgba(0,0,0,0.3);\n border: 1px solid var(--border);\n border-radius: 6px;\n padding: 10px;\n font-size: 12px;\n color: var(--text2);\n line-height: 1.6;\n max-height: 160px;\n overflow-y: auto;\n}\n\n/* Children list */\n.children-list {\n list-style: none;\n padding: 0;\n font-size: 12px;\n}\n.children-list li {\n padding: 3px 0;\n display: flex;\n align-items: center;\n gap: 6px;\n}\n.children-list li::before {\n content: '';\n display: inline-block;\n width: 6px; height: 6px;\n border-radius: 50%;\n background: var(--lightcyan);\n}\n\n/* Task history */\n#task-history {\n max-height: 250px;\n overflow-y: auto;\n}\n.history-item {\n font-size: 11px;\n padding: 4px 0;\n border-bottom: 1px solid rgba(30,41,59,0.5);\n color: var(--text2);\n}\n\n/* ===================================================================\n EVENT LOG\n =================================================================== */\n#event-log {\n grid-area: log;\n background: var(--surface);\n border-top: 1px solid var(--border);\n display: flex;\n flex-direction: column;\n overflow: hidden;\n}\n\n#event-log .log-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 6px 16px;\n font-size: 10px;\n text-transform: uppercase;\n letter-spacing: 2px;\n color: var(--text2);\n border-bottom: 1px solid var(--border);\n flex-shrink: 0;\n}\n#event-log .log-header .pause-indicator {\n color: var(--warning);\n font-weight: 600;\n display: none;\n}\n#event-log .log-header .pause-indicator.visible {\n display: inline;\n}\n\n#log-entries {\n flex: 1;\n overflow-y: auto;\n padding: 4px 0;\n font-size: 12px;\n scroll-behavior: smooth;\n}\n\n.log-entry {\n display: flex;\n gap: 12px;\n padding: 3px 16px;\n border-bottom: 1px solid rgba(30,41,59,0.3);\n align-items: baseline;\n}\n.log-entry:hover { background: rgba(255,255,255,0.02); }\n\n.log-time {\n color: var(--text2);\n font-size: 11px;\n flex-shrink: 0;\n min-width: 64px;\n}\n.log-session {\n color: var(--cyan);\n font-size: 10px;\n flex-shrink: 0;\n min-width: 80px;\n max-width: 120px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n opacity: 0.7;\n}\n.log-kind {\n font-weight: 600;\n flex-shrink: 0;\n min-width: 90px;\n font-size: 11px;\n}\n.log-msg {\n color: var(--text);\n flex: 1;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n/* Kind colours */\n.log-kind.spawn { color: var(--cyan); }\n.log-kind.destroy { color: var(--error); }\n.log-kind.state { color: var(--purple); }\n.log-kind.task { color: var(--lightcyan); }\n.log-kind.done { color: var(--success); }\n.log-kind.msg { color: var(--text); }\n.log-kind.mention { color: var(--error); }\n.log-kind.resolved { color: var(--success); }\n.log-kind.cost { color: var(--warning); }\n.log-kind.session { color: var(--purple); }\n\n/* ===================================================================\n ANIMATIONS\n =================================================================== */\n@keyframes breathe {\n 0%, 100% { opacity: 0.4; }\n 50% { opacity: 1; }\n}\n@keyframes pulse-glow {\n 0%, 100% { box-shadow: 0 0 4px rgba(0,240,255,0.3); }\n 50% { box-shadow: 0 0 18px rgba(0,240,255,0.7); }\n}\n\n/* Custom scrollbar */\n::-webkit-scrollbar { width: 6px; }\n::-webkit-scrollbar-track { background: var(--bg); }\n::-webkit-scrollbar-thumb { background: var(--border); border-radius: 3px; }\n::-webkit-scrollbar-thumb:hover { background: #334155; }\n</style>\n</head>\n<body>\n\n<div id=\"app\">\n <!-- HEADER ------------------------------------------------------------ -->\n <header id=\"header\">\n <div class=\"brand\">\n <span style=\"font-size:22px\">&#x1F96C;</span>\n <span>Open Coleslaw</span>\n </div>\n <div class=\"center-status\">\n <span class=\"conn-dot\" id=\"conn-dot\"></span>\n <span id=\"conn-label\">Connecting...</span>\n </div>\n <div class=\"right-stats\">\n <span class=\"badge\" id=\"badge-sessions\">0 sessions</span>\n <span class=\"badge\" id=\"badge-agents\">0 agents</span>\n <span class=\"badge purple\" id=\"badge-meeting\">No meeting</span>\n <span class=\"badge green\" id=\"badge-cost\">$0.0000</span>\n </div>\n </header>\n\n <!-- TAB BAR ----------------------------------------------------------- -->\n <div id=\"tab-bar\">\n <span class=\"tab-empty-msg\" id=\"tab-empty\">Waiting for sessions...</span>\n </div>\n\n <!-- GRAPH ------------------------------------------------------------- -->\n <div id=\"graph-container\">\n <div id=\"cy\"></div>\n </div>\n\n <!-- SIDEBAR ----------------------------------------------------------- -->\n <aside id=\"sidebar\">\n <h2>Agent Details</h2>\n <div class=\"sidebar-empty\" id=\"sidebar-empty\">Click a node to inspect</div>\n <div id=\"sidebar-content\" style=\"display:none;\"></div>\n </aside>\n\n <!-- EVENT LOG --------------------------------------------------------- -->\n <div id=\"event-log\">\n <div class=\"log-header\">\n <span>Event Log</span>\n <span class=\"pause-indicator\" id=\"log-pause\">PAUSED (scroll up)</span>\n </div>\n <div id=\"log-entries\"></div>\n </div>\n</div>\n\n<script>\n// ======================================================================\n// IIFE -- all dashboard JS\n// ======================================================================\n(function () {\n 'use strict';\n\n // ====================================================================\n // 1. STATE STORE (per-session)\n // ====================================================================\n // sessions: Map<sessionId, { displayName, projectPath, isActive, agents: Map, edges: [], meeting, totalCost, eventHistory[] }>\n const sessions = new Map();\n let activeTabId = null; // currently viewed session\n let selectedAgentId = null; // clicked node\n\n function getSession(id) { return sessions.get(id); }\n\n function activeSession() {\n if (!activeTabId) return null;\n return sessions.get(activeTabId) || null;\n }\n\n // ====================================================================\n // 2. CONNECTION MANAGER -- WebSocket with exponential backoff\n // ====================================================================\n const ConnectionManager = {\n ws: null,\n backoff: 1000,\n maxBackoff: 30000,\n timer: null,\n _heartbeat: null,\n\n connect() {\n const proto = location.protocol === 'https:' ? 'wss' : 'ws';\n const url = proto + '://' + location.host;\n this.ws = new WebSocket(url);\n this.setStatus('reconnecting');\n\n this.ws.onopen = () => {\n this.backoff = 1000;\n this.setStatus('connected');\n };\n\n this.ws.onmessage = (msg) => {\n try {\n const data = JSON.parse(msg.data);\n this.handleMessage(data);\n } catch (e) {\n console.error('[WS] Parse error:', e);\n }\n };\n\n this.ws.onclose = () => {\n this.setStatus('disconnected');\n this.scheduleReconnect();\n };\n\n this.ws.onerror = () => {};\n\n if (this._heartbeat) clearInterval(this._heartbeat);\n this._heartbeat = setInterval(() => {\n if (this.ws && this.ws.readyState === WebSocket.OPEN) {\n this.ws.send(JSON.stringify({ type: 'ping' }));\n }\n }, 25000);\n },\n\n handleMessage(data) {\n switch (data.type) {\n case 'multi-snapshot':\n this.handleMultiSnapshot(data);\n break;\n case 'session-delta':\n this.handleSessionDelta(data);\n break;\n case 'session-registered':\n this.handleSessionRegistered(data);\n break;\n case 'session-unregistered':\n this.handleSessionUnregistered(data);\n break;\n case 'pong':\n break;\n default:\n break;\n }\n },\n\n handleMultiSnapshot(data) {\n sessions.clear();\n (data.sessions || []).forEach(function (s) {\n var agentsMap = new Map();\n (s.snapshot.agents || []).forEach(function (a) { agentsMap.set(a.id, a); });\n sessions.set(s.sessionId, {\n displayName: s.displayName,\n projectPath: s.projectPath,\n isActive: s.isActive,\n agents: agentsMap,\n edges: s.snapshot.edges || [],\n meeting: s.snapshot.meeting || null,\n totalCost: s.snapshot.totalCost || 0,\n eventHistory: [],\n });\n });\n // Auto-select first active tab if none selected\n if (!activeTabId || !sessions.has(activeTabId)) {\n var first = null;\n sessions.forEach(function (s, id) { if (!first && s.isActive) first = id; });\n if (!first && sessions.size > 0) first = sessions.keys().next().value;\n activeTabId = first;\n }\n TabBar.render();\n StatusBar.update();\n GraphRenderer.rebuild();\n },\n\n handleSessionDelta(data) {\n var sess = sessions.get(data.sessionId);\n if (!sess) {\n // Session not yet known -- create a placeholder\n sess = {\n displayName: data.displayName,\n projectPath: '',\n isActive: true,\n agents: new Map(),\n edges: [],\n meeting: null,\n totalCost: 0,\n eventHistory: [],\n };\n sessions.set(data.sessionId, sess);\n TabBar.render();\n }\n\n (data.events || []).forEach(function (ev) {\n applyEventToSession(data.sessionId, sess, ev);\n });\n\n TabBar.updateBadge(data.sessionId);\n StatusBar.update();\n\n // Rebuild graph only if this is the active tab\n if (data.sessionId === activeTabId) {\n GraphRenderer.rebuild();\n if (selectedAgentId) SidebarPanel.show(selectedAgentId);\n }\n },\n\n handleSessionRegistered(data) {\n if (!sessions.has(data.sessionId)) {\n sessions.set(data.sessionId, {\n displayName: data.displayName,\n projectPath: data.projectPath,\n isActive: true,\n agents: new Map(),\n edges: [],\n meeting: null,\n totalCost: 0,\n eventHistory: [],\n });\n }\n // Auto-select if no tab is active\n if (!activeTabId) activeTabId = data.sessionId;\n TabBar.render();\n StatusBar.update();\n EventLog.appendSystem(data.displayName, 'Session connected');\n },\n\n handleSessionUnregistered(data) {\n var sess = sessions.get(data.sessionId);\n if (sess) {\n sess.isActive = false;\n TabBar.render();\n StatusBar.update();\n EventLog.appendSystem(sess.displayName, 'Session disconnected');\n }\n },\n\n scheduleReconnect() {\n if (this.timer) clearTimeout(this.timer);\n this.timer = setTimeout(() => {\n this.backoff = Math.min(this.backoff * 2, this.maxBackoff);\n this.connect();\n }, this.backoff);\n },\n\n setStatus(status) {\n var dot = document.getElementById('conn-dot');\n var label = document.getElementById('conn-label');\n dot.className = 'conn-dot';\n if (status === 'connected') {\n dot.classList.add('connected');\n label.textContent = 'Connected';\n } else if (status === 'reconnecting') {\n dot.classList.add('reconnecting');\n label.textContent = 'Connecting...';\n } else {\n label.textContent = 'Disconnected';\n }\n },\n };\n\n // ====================================================================\n // Event application (scoped to a session)\n // ====================================================================\n function applyEventToSession(sessionId, sess, ev) {\n sess.eventHistory.push(ev);\n if (sess.eventHistory.length > 500) sess.eventHistory.shift();\n\n EventLog.append(sessionId, sess.displayName, ev);\n\n switch (ev.kind) {\n case 'agent_spawned': {\n var agent = {\n id: ev.agentId,\n type: ev.agentType,\n label: ev.label,\n status: 'idle',\n parentId: ev.parentId,\n department: ev.department,\n currentTask: null,\n costUsd: 0,\n };\n sess.agents.set(ev.agentId, agent);\n if (ev.parentId) {\n sess.edges.push({\n id: 'edge-' + ev.parentId + '-' + ev.agentId,\n source: ev.parentId,\n target: ev.agentId,\n edgeType: 'hierarchy',\n active: true,\n label: '',\n });\n }\n break;\n }\n case 'agent_destroyed': {\n sess.agents.delete(ev.agentId);\n sess.edges = sess.edges.filter(function (e) {\n return e.source !== ev.agentId && e.target !== ev.agentId;\n });\n if (sessionId === activeTabId && selectedAgentId === ev.agentId) {\n selectedAgentId = null;\n SidebarPanel.clear();\n }\n break;\n }\n case 'state_changed': {\n var a = sess.agents.get(ev.agentId);\n if (a) a.status = ev.to;\n break;\n }\n case 'task_assigned': {\n var a = sess.agents.get(ev.agentId);\n if (a) { a.currentTask = ev.taskSummary; a.status = 'working'; }\n break;\n }\n case 'task_completed': {\n var a = sess.agents.get(ev.agentId);\n if (a) { a.currentTask = null; a.status = ev.result === 'success' ? 'completed' : 'failed'; }\n break;\n }\n case 'message_sent': {\n var edgeId = 'msg-' + ev.fromId + '-' + ev.toId + '-' + Date.now();\n var edge = { id: edgeId, source: ev.fromId, target: ev.toId, edgeType: 'message', active: true, label: ev.summary };\n sess.edges.push(edge);\n setTimeout(function () {\n sess.edges = sess.edges.filter(function (e) { return e.id !== edgeId; });\n if (sessionId === activeTabId) GraphRenderer.rebuild();\n }, 5000);\n break;\n }\n case 'cost_update': {\n sess.totalCost = ev.totalCost;\n break;\n }\n default:\n break;\n }\n }\n\n // ====================================================================\n // 3. TAB BAR\n // ====================================================================\n var TabBar = {\n render: function () {\n var bar = document.getElementById('tab-bar');\n var emptyMsg = document.getElementById('tab-empty');\n\n // Remove old tabs (keep the empty msg span)\n var old = bar.querySelectorAll('.session-tab');\n old.forEach(function (el) { el.remove(); });\n\n if (sessions.size === 0) {\n emptyMsg.style.display = '';\n return;\n }\n emptyMsg.style.display = 'none';\n\n sessions.forEach(function (sess, sessionId) {\n var tab = document.createElement('button');\n tab.className = 'session-tab';\n if (sessionId === activeTabId) tab.classList.add('active');\n if (!sess.isActive) tab.classList.add('inactive');\n tab.dataset.sessionId = sessionId;\n\n // Tab label\n var lbl = document.createElement('span');\n lbl.textContent = sess.displayName || sessionId.slice(0, 8);\n tab.appendChild(lbl);\n\n // Agent count badge\n var badge = document.createElement('span');\n badge.className = 'tab-badge';\n badge.textContent = String(sess.agents.size);\n tab.appendChild(badge);\n\n // Meeting indicator\n if (sess.meeting) {\n var mb = document.createElement('span');\n mb.className = 'tab-badge meeting';\n mb.textContent = 'MTG';\n tab.appendChild(mb);\n }\n\n tab.addEventListener('click', function () {\n TabBar.switchTo(sessionId);\n });\n\n bar.appendChild(tab);\n });\n },\n\n switchTo: function (sessionId) {\n activeTabId = sessionId;\n selectedAgentId = null;\n SidebarPanel.clear();\n this.render();\n StatusBar.update();\n GraphRenderer.rebuild();\n },\n\n updateBadge: function (sessionId) {\n var bar = document.getElementById('tab-bar');\n var tabs = bar.querySelectorAll('.session-tab');\n tabs.forEach(function (tab) {\n if (tab.dataset.sessionId === sessionId) {\n var sess = sessions.get(sessionId);\n if (!sess) return;\n var badge = tab.querySelector('.tab-badge:not(.meeting)');\n if (badge) badge.textContent = String(sess.agents.size);\n }\n });\n },\n };\n\n // ====================================================================\n // 4. GRAPH RENDERER -- Cytoscape.js\n // ====================================================================\n var GraphRenderer = {\n cy: null,\n _layoutTimer: null,\n _animFrame: null,\n _dashOffset: 0,\n\n init: function () {\n this.cy = cytoscape({\n container: document.getElementById('cy'),\n style: [\n // --- NODES ---\n {\n selector: 'node',\n style: {\n 'label': 'data(label)',\n 'text-valign': 'bottom',\n 'text-halign': 'center',\n 'text-margin-y': 8,\n 'font-family': \"'JetBrains Mono', monospace\",\n 'font-size': 10,\n 'color': '#94a3b8',\n 'text-outline-width': 0,\n 'background-color': '#1e293b',\n 'border-width': 2,\n 'border-color': '#334155',\n 'width': 40,\n 'height': 40,\n 'transition-property': 'background-color, border-color, border-width, opacity, width, height',\n 'transition-duration': '0.3s',\n },\n },\n // Orchestrator\n {\n selector: 'node[tier=\"orchestrator\"]',\n style: {\n 'width': 60, 'height': 60,\n 'border-width': 3,\n 'border-color': '#00f0ff',\n 'background-color': 'rgba(0,240,255,0.1)',\n 'color': '#00f0ff',\n 'font-size': 12, 'font-weight': '700',\n 'text-outline-color': '#0a0e17',\n 'text-outline-width': 2,\n },\n },\n // Leader\n {\n selector: 'node[tier=\"leader\"]',\n style: {\n 'width': 48, 'height': 48,\n 'border-width': 2,\n 'border-color': '#a855f7',\n 'background-color': 'rgba(168,85,247,0.1)',\n 'color': '#a855f7',\n 'font-size': 11, 'font-weight': '600',\n },\n },\n // Worker\n {\n selector: 'node[tier=\"worker\"]',\n style: {\n 'width': 36, 'height': 36,\n 'border-width': 2,\n 'border-color': '#22d3ee',\n 'background-color': 'rgba(34,211,238,0.08)',\n 'color': '#22d3ee',\n 'font-size': 10,\n },\n },\n // Status: idle\n { selector: 'node[status=\"idle\"]', style: { 'opacity': 0.5, 'border-color': '#475569' } },\n // Status: working\n { selector: 'node[status=\"working\"]', style: { 'border-width': 3, 'opacity': 1 } },\n // Status: in-meeting\n { selector: 'node[status=\"in-meeting\"]', style: { 'border-color': '#f59e0b', 'background-color': 'rgba(245,158,11,0.1)', 'opacity': 1 } },\n // Status: spawning-workers\n { selector: 'node[status=\"spawning-workers\"]', style: { 'border-color': '#a855f7', 'opacity': 1 } },\n // Status: waiting-for-user\n { selector: 'node[status=\"waiting-for-user\"]', style: { 'border-color': '#f59e0b', 'opacity': 0.8 } },\n // Status: aggregating\n { selector: 'node[status=\"aggregating\"]', style: { 'border-color': '#22d3ee', 'opacity': 1 } },\n // Status: completed\n { selector: 'node[status=\"completed\"]', style: { 'border-color': '#10b981', 'background-color': 'rgba(16,185,129,0.1)', 'opacity': 0.7 } },\n // Status: failed\n { selector: 'node[status=\"failed\"]', style: { 'border-color': '#ef4444', 'background-color': 'rgba(239,68,68,0.1)', 'opacity': 0.8 } },\n // Selected node\n { selector: 'node:selected', style: { 'border-width': 4, 'overlay-padding': 6, 'overlay-color': '#00f0ff', 'overlay-opacity': 0.08 } },\n // --- EDGES ---\n {\n selector: 'edge',\n style: {\n 'width': 1.5,\n 'line-color': '#334155',\n 'target-arrow-color': '#334155',\n 'target-arrow-shape': 'triangle',\n 'arrow-scale': 0.8,\n 'curve-style': 'bezier',\n 'opacity': 0.5,\n 'transition-property': 'line-color, opacity, width',\n 'transition-duration': '0.3s',\n },\n },\n { selector: 'edge[edgeType=\"hierarchy\"][?active]', style: { 'line-color': '#475569', 'target-arrow-color': '#475569', 'line-style': 'solid', 'opacity': 0.6, 'width': 1.5 } },\n { selector: 'edge[edgeType=\"delegation\"]', style: { 'line-color': '#a855f7', 'target-arrow-color': '#a855f7', 'line-style': 'dashed', 'line-dash-pattern': [8, 4], 'opacity': 0.8, 'width': 2 } },\n { selector: 'edge[edgeType=\"report\"]', style: { 'line-color': '#10b981', 'target-arrow-color': '#10b981', 'opacity': 0.8, 'width': 2 } },\n { selector: 'edge[edgeType=\"message\"]', style: { 'line-color': '#22d3ee', 'target-arrow-color': '#22d3ee', 'line-style': 'dashed', 'line-dash-pattern': [6, 3], 'opacity': 0.7, 'width': 1.5 } },\n { selector: 'edge[edgeType=\"mention\"]', style: { 'line-color': '#ef4444', 'target-arrow-color': '#ef4444', 'line-style': 'dashed', 'line-dash-pattern': [4, 4], 'opacity': 0.9, 'width': 2.5 } },\n ],\n layout: { name: 'preset' },\n minZoom: 0.3,\n maxZoom: 3,\n wheelSensitivity: 0.3,\n });\n\n // Click handling\n this.cy.on('tap', 'node', function (evt) {\n var id = evt.target.id();\n selectedAgentId = id;\n SidebarPanel.show(id);\n });\n\n this.cy.on('tap', function (evt) {\n if (evt.target === GraphRenderer.cy) {\n selectedAgentId = null;\n SidebarPanel.clear();\n }\n });\n\n this.startAnimations();\n },\n\n rebuild: function () {\n if (!this.cy) return;\n this.cy.elements().remove();\n\n var sess = activeSession();\n if (!sess) return;\n\n sess.agents.forEach(function (agent) {\n GraphRenderer.cy.add({\n group: 'nodes',\n data: {\n id: agent.id,\n label: agent.label,\n tier: agent.type,\n status: agent.status,\n department: agent.department,\n },\n });\n });\n\n sess.edges.forEach(function (edge) {\n if (GraphRenderer.cy.getElementById(edge.source).length && GraphRenderer.cy.getElementById(edge.target).length) {\n GraphRenderer.cy.add({\n group: 'edges',\n data: {\n id: edge.id,\n source: edge.source,\n target: edge.target,\n edgeType: edge.edgeType,\n active: edge.active,\n },\n });\n }\n });\n\n this.runLayout();\n },\n\n runLayout: function () {\n if (!this.cy || this.cy.nodes().length === 0) return;\n this.cy.layout({\n name: 'dagre',\n rankDir: 'TB',\n rankSep: 80,\n nodeSep: 40,\n edgeSep: 20,\n animate: true,\n animationDuration: 500,\n animationEasing: 'ease-out',\n padding: 40,\n }).run();\n },\n\n startAnimations: function () {\n var self = this;\n var animate = function () {\n self._dashOffset += 0.5;\n if (self.cy) {\n self.cy.edges('[edgeType=\"delegation\"], [edgeType=\"message\"], [edgeType=\"mention\"]').forEach(function (edge) {\n edge.style('line-dash-offset', -self._dashOffset);\n });\n\n var t = Date.now();\n self.cy.nodes('[status=\"working\"]').forEach(function (node) {\n var glow = 2 + Math.sin(t / 400) * 1;\n node.style('border-width', glow);\n });\n self.cy.nodes('[status=\"in-meeting\"]').forEach(function (node) {\n var op = 0.4 + (Math.sin(t / 1000) + 1) * 0.3;\n node.style('opacity', op);\n });\n self.cy.nodes('[status=\"waiting-for-user\"]').forEach(function (node) {\n var op = 0.5 + (Math.sin(t / 1500) + 1) * 0.25;\n node.style('opacity', op);\n });\n self.cy.nodes('[status=\"spawning-workers\"]').forEach(function (node) {\n var c = Math.sin(t / 600) > 0 ? '#a855f7' : '#22d3ee';\n node.style('border-color', c);\n });\n }\n self._animFrame = requestAnimationFrame(animate);\n };\n self._animFrame = requestAnimationFrame(animate);\n },\n };\n\n // ====================================================================\n // 5. SIDEBAR PANEL\n // ====================================================================\n var SidebarPanel = {\n show: function (agentId) {\n var sess = activeSession();\n if (!sess) { this.clear(); return; }\n var agent = sess.agents.get(agentId);\n if (!agent) { this.clear(); return; }\n\n document.getElementById('sidebar-empty').style.display = 'none';\n var el = document.getElementById('sidebar-content');\n el.style.display = 'block';\n\n // Children\n var children = [];\n sess.agents.forEach(function (a) {\n if (a.parentId === agentId) children.push(a);\n });\n\n // Recent events for this agent\n var recentEvents = sess.eventHistory\n .filter(function (ev) { return ev.agentId === agentId || ev.fromId === agentId || ev.toId === agentId; })\n .slice(-10)\n .reverse();\n\n var tierIcon = agent.type === 'orchestrator' ? '&#x1F3AF;' : agent.type === 'leader' ? '&#x1F451;' : '&#x2699;&#xFE0F;';\n\n el.innerHTML =\n '<div style=\"text-align:center;margin-bottom:8px;\">' +\n '<span style=\"font-size:28px;\">' + tierIcon + '</span>' +\n '<div style=\"font-size:14px;font-weight:700;color:var(--cyan);margin-top:4px;\">' + escHtml(agent.label) + '</div>' +\n '<div style=\"font-size:11px;color:var(--text2);\">' + escHtml(agent.id) + '</div>' +\n '</div>' +\n '<div class=\"detail-row\"><span class=\"label\">Type</span><span class=\"value\">' + agent.type + '</span></div>' +\n '<div class=\"detail-row\"><span class=\"label\">Department</span><span class=\"value\">' + escHtml(agent.department) + '</span></div>' +\n '<div class=\"detail-row\"><span class=\"label\">Status</span><span class=\"value\"><span class=\"status-chip ' + agent.status + '\">' + agent.status + '</span></span></div>' +\n '<div class=\"detail-row\"><span class=\"label\">Cost</span><span class=\"value\">$' + agent.costUsd.toFixed(4) + '</span></div>' +\n '<div class=\"detail-row\"><span class=\"label\">Workers</span><span class=\"value\">' + children.length + '</span></div>' +\n (agent.currentTask\n ? '<h2 style=\"margin-top:12px;\">Current Task</h2><div class=\"task-block\">' + escHtml(agent.currentTask) + '</div>'\n : '') +\n (children.length > 0\n ? '<h2 style=\"margin-top:12px;\">Children</h2><ul class=\"children-list\">' +\n children.map(function (c) { return '<li>' + escHtml(c.label) + ' <span class=\"status-chip ' + c.status + '\" style=\"font-size:10px;\">' + c.status + '</span></li>'; }).join('') +\n '</ul>'\n : '') +\n (recentEvents.length > 0\n ? '<h2 style=\"margin-top:12px;\">Recent Activity</h2><div id=\"task-history\">' +\n recentEvents.map(function (ev) { return '<div class=\"history-item\">' + summarizeEventShort(ev) + '</div>'; }).join('') +\n '</div>'\n : '');\n },\n\n clear: function () {\n document.getElementById('sidebar-empty').style.display = 'block';\n document.getElementById('sidebar-content').style.display = 'none';\n },\n };\n\n // ====================================================================\n // 6. EVENT LOG\n // ====================================================================\n var EventLog = {\n el: null,\n pauseEl: null,\n autoScroll: true,\n maxEntries: 500,\n\n init: function () {\n this.el = document.getElementById('log-entries');\n this.pauseEl = document.getElementById('log-pause');\n var self = this;\n this.el.addEventListener('scroll', function () {\n var atBottom = self.el.scrollHeight - self.el.scrollTop - self.el.clientHeight < 30;\n self.autoScroll = atBottom;\n self.pauseEl.classList.toggle('visible', !atBottom);\n });\n },\n\n append: function (sessionId, displayName, ev) {\n var row = document.createElement('div');\n row.className = 'log-entry';\n\n var now = new Date();\n var ts = pad2(now.getHours()) + ':' + pad2(now.getMinutes()) + ':' + pad2(now.getSeconds());\n\n var kindLabel = '';\n var kindClass = '';\n var message = '';\n\n switch (ev.kind) {\n case 'agent_spawned':\n kindLabel = 'SPAWN'; kindClass = 'spawn';\n message = '<b>' + escHtml(ev.label) + '</b> (' + ev.agentType + ') in ' + escHtml(ev.department);\n break;\n case 'agent_destroyed':\n kindLabel = 'DESTROY'; kindClass = 'destroy';\n message = escHtml(ev.agentId);\n break;\n case 'state_changed':\n kindLabel = 'STATE'; kindClass = 'state';\n message = escHtml(ev.agentId) + ': ' + ev.from + ' &#x2192; ' + ev.to;\n break;\n case 'task_assigned':\n kindLabel = 'TASK'; kindClass = 'task';\n message = escHtml(ev.agentId) + ': ' + escHtml(ev.taskSummary);\n break;\n case 'task_completed':\n kindLabel = ev.result === 'success' ? 'SUCCESS' : 'FAILED';\n kindClass = ev.result === 'success' ? 'done' : 'destroy';\n message = escHtml(ev.agentId);\n break;\n case 'message_sent':\n kindLabel = 'MSG'; kindClass = 'msg';\n message = escHtml(ev.fromId) + ' &#x2192; ' + escHtml(ev.toId) + ': ' + escHtml(ev.summary);\n break;\n case 'mention_created':\n kindLabel = '@MENTION'; kindClass = 'mention';\n message = escHtml(ev.summary) + ' [' + ev.urgency + ']';\n break;\n case 'mention_resolved':\n kindLabel = '@RESOLVED'; kindClass = 'resolved';\n message = escHtml(ev.mentionId) + ': ' + escHtml(ev.decision);\n break;\n case 'cost_update':\n kindLabel = 'COST'; kindClass = 'cost';\n message = 'Total: $' + ev.totalCost.toFixed(4);\n break;\n default:\n kindLabel = 'EVENT'; kindClass = '';\n message = JSON.stringify(ev);\n }\n\n row.innerHTML =\n '<span class=\"log-time\">' + ts + '</span>' +\n '<span class=\"log-session\">' + escHtml(displayName) + '</span>' +\n '<span class=\"log-kind ' + kindClass + '\">' + kindLabel + '</span>' +\n '<span class=\"log-msg\">' + message + '</span>';\n\n this.el.appendChild(row);\n\n while (this.el.children.length > this.maxEntries) {\n this.el.removeChild(this.el.firstChild);\n }\n\n if (this.autoScroll) {\n this.el.scrollTop = this.el.scrollHeight;\n }\n },\n\n appendSystem: function (displayName, message) {\n var row = document.createElement('div');\n row.className = 'log-entry';\n var now = new Date();\n var ts = pad2(now.getHours()) + ':' + pad2(now.getMinutes()) + ':' + pad2(now.getSeconds());\n row.innerHTML =\n '<span class=\"log-time\">' + ts + '</span>' +\n '<span class=\"log-session\">' + escHtml(displayName) + '</span>' +\n '<span class=\"log-kind session\">SESSION</span>' +\n '<span class=\"log-msg\">' + escHtml(message) + '</span>';\n this.el.appendChild(row);\n if (this.autoScroll) this.el.scrollTop = this.el.scrollHeight;\n },\n };\n\n // ====================================================================\n // 7. STATUS BAR\n // ====================================================================\n var StatusBar = {\n update: function () {\n // Session count\n var totalSessions = sessions.size;\n var activeSessions = 0;\n sessions.forEach(function (s) { if (s.isActive) activeSessions++; });\n document.getElementById('badge-sessions').textContent = activeSessions + '/' + totalSessions + ' sessions';\n\n // Agent count + meeting + cost for active tab\n var sess = activeSession();\n if (sess) {\n document.getElementById('badge-agents').textContent = sess.agents.size + ' agent' + (sess.agents.size !== 1 ? 's' : '');\n\n if (sess.meeting) {\n document.getElementById('badge-meeting').textContent = sess.meeting.phase;\n document.getElementById('badge-meeting').className = 'badge amber';\n } else {\n document.getElementById('badge-meeting').textContent = 'No meeting';\n document.getElementById('badge-meeting').className = 'badge purple';\n }\n\n document.getElementById('badge-cost').textContent = '$' + sess.totalCost.toFixed(4);\n } else {\n document.getElementById('badge-agents').textContent = '0 agents';\n document.getElementById('badge-meeting').textContent = 'No meeting';\n document.getElementById('badge-meeting').className = 'badge purple';\n document.getElementById('badge-cost').textContent = '$0.0000';\n }\n },\n };\n\n // ====================================================================\n // HELPERS\n // ====================================================================\n function escHtml(str) {\n if (typeof str !== 'string') return String(str || '');\n return str.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/\"/g, '&quot;');\n }\n\n function pad2(n) {\n return n < 10 ? '0' + n : String(n);\n }\n\n function summarizeEventShort(ev) {\n switch (ev.kind) {\n case 'agent_spawned': return 'Spawned: ' + escHtml(ev.label);\n case 'agent_destroyed': return 'Destroyed';\n case 'state_changed': return ev.from + ' &#x2192; ' + ev.to;\n case 'task_assigned': return 'Task: ' + escHtml(ev.taskSummary);\n case 'task_completed': return 'Completed: ' + ev.result;\n case 'message_sent': return 'Msg to ' + escHtml(ev.toId);\n case 'mention_created': return '@mention: ' + escHtml(ev.summary);\n case 'mention_resolved': return '@resolved: ' + escHtml(ev.decision);\n case 'cost_update': return 'Cost: $' + ev.totalCost.toFixed(4);\n default: return ev.kind;\n }\n }\n\n // ====================================================================\n // BOOT\n // ====================================================================\n document.addEventListener('DOMContentLoaded', function () {\n GraphRenderer.init();\n EventLog.init();\n StatusBar.update();\n ConnectionManager.connect();\n });\n\n})();\n</script>\n</body>\n</html>`;\n}\n","/**\n * StateBridge — manages per-session state and emits 'broadcast' events\n * for the dashboard server to relay to browser WebSocket clients.\n *\n * Supports multiple sessions (one per MCP server instance). Each session\n * tracks its own agent graph independently. Disconnected sessions are kept\n * (grayed-out tab) rather than deleted.\n */\n\nimport { EventEmitter } from 'node:events';\nimport type {\n AgentState,\n EdgeState,\n MeetingState,\n AgentEvent,\n MultiSessionSnapshot,\n SessionDelta,\n} from '../types/dashboard-events.js';\nimport { logger } from '../utils/logger.js';\n\n// ---------------------------------------------------------------------------\n// Per-session state container\n// ---------------------------------------------------------------------------\n\ninterface SessionState {\n projectName: string;\n displayName: string;\n projectPath: string;\n isActive: boolean;\n agents: Map<string, AgentState>;\n edges: EdgeState[];\n meeting: MeetingState | null;\n totalCost: number;\n eventLog: Array<{ timestamp: number; event: AgentEvent }>;\n}\n\n// ---------------------------------------------------------------------------\n// StateBridge\n// ---------------------------------------------------------------------------\n\nexport class StateBridge extends EventEmitter {\n private sessions = new Map<string, SessionState>();\n private debounceTimers = new Map<string, NodeJS.Timeout>();\n private pendingEvents = new Map<string, AgentEvent[]>();\n\n // -----------------------------------------------------------------------\n // Session lifecycle\n // -----------------------------------------------------------------------\n\n registerSession(info: {\n sessionId: string;\n projectPath: string;\n projectName: string;\n }): string {\n const displayName = this.getUniqueDisplayName(info.projectName);\n\n this.sessions.set(info.sessionId, {\n projectName: info.projectName,\n displayName,\n projectPath: info.projectPath,\n isActive: true,\n agents: new Map(),\n edges: [],\n meeting: null,\n totalCost: 0,\n eventLog: [],\n });\n\n logger.info(`Session registered: ${displayName} (${info.sessionId})`);\n\n // Notify browser clients about the new session\n this.emit(\n 'broadcast',\n JSON.stringify({\n type: 'session-registered',\n sessionId: info.sessionId,\n displayName,\n projectPath: info.projectPath,\n }),\n );\n\n return displayName;\n }\n\n unregisterSession(sessionId: string): void {\n const session = this.sessions.get(sessionId);\n if (session) {\n session.isActive = false;\n logger.info(`Session deactivated: ${session.displayName}`);\n\n // Don't delete — keep for display (grayed-out tab)\n this.emit(\n 'broadcast',\n JSON.stringify({\n type: 'session-unregistered',\n sessionId,\n }),\n );\n }\n }\n\n // -----------------------------------------------------------------------\n // Event handling\n // -----------------------------------------------------------------------\n\n handleSessionEvent(sessionId: string, event: AgentEvent): void {\n const session = this.sessions.get(sessionId);\n if (!session) return;\n\n // Apply event to session state\n this.applyEvent(session, event);\n\n // Queue for debounced broadcast\n if (!this.pendingEvents.has(sessionId)) {\n this.pendingEvents.set(sessionId, []);\n }\n this.pendingEvents.get(sessionId)!.push(event);\n\n // Debounce broadcast per session (100ms)\n if (!this.debounceTimers.has(sessionId)) {\n this.debounceTimers.set(\n sessionId,\n setTimeout(() => {\n this.flushEvents(sessionId);\n this.debounceTimers.delete(sessionId);\n }, 100),\n );\n }\n }\n\n // -----------------------------------------------------------------------\n // Snapshot (sent to newly connected browser clients)\n // -----------------------------------------------------------------------\n\n getSnapshot(): MultiSessionSnapshot {\n return {\n type: 'multi-snapshot',\n sessions: Array.from(this.sessions.entries()).map(([sessionId, s]) => ({\n sessionId,\n displayName: s.displayName,\n projectPath: s.projectPath,\n isActive: s.isActive,\n snapshot: {\n agents: Array.from(s.agents.values()),\n edges: [...s.edges],\n meeting: s.meeting,\n totalCost: s.totalCost,\n },\n })),\n };\n }\n\n // -----------------------------------------------------------------------\n // Private — unique display name\n // -----------------------------------------------------------------------\n\n private getUniqueDisplayName(projectName: string): string {\n const existing = Array.from(this.sessions.values()).map(\n (s) => s.displayName,\n );\n if (!existing.includes(projectName)) return projectName;\n let i = 1;\n while (existing.includes(`${projectName} (${i})`)) i++;\n return `${projectName} (${i})`;\n }\n\n // -----------------------------------------------------------------------\n // Private — state mutations (scoped to a session)\n // -----------------------------------------------------------------------\n\n private applyEvent(session: SessionState, event: AgentEvent): void {\n session.eventLog.push({ timestamp: Date.now(), event });\n // Keep log bounded\n if (session.eventLog.length > 500) session.eventLog.shift();\n\n switch (event.kind) {\n case 'agent_spawned': {\n const agent: AgentState = {\n id: event.agentId,\n type: event.agentType,\n label: event.label,\n status: 'idle',\n parentId: event.parentId,\n department: event.department,\n currentTask: null,\n costUsd: 0,\n };\n session.agents.set(event.agentId, agent);\n\n if (event.parentId) {\n session.edges.push({\n id: `edge-${event.parentId}-${event.agentId}`,\n source: event.parentId,\n target: event.agentId,\n edgeType: 'hierarchy',\n active: true,\n label: '',\n });\n }\n break;\n }\n\n case 'agent_destroyed': {\n session.agents.delete(event.agentId);\n session.edges = session.edges.filter(\n (e) => e.source !== event.agentId && e.target !== event.agentId,\n );\n break;\n }\n\n case 'state_changed': {\n const a = session.agents.get(event.agentId);\n if (a) a.status = event.to;\n break;\n }\n\n case 'task_assigned': {\n const a = session.agents.get(event.agentId);\n if (a) {\n a.currentTask = event.taskSummary;\n a.status = 'working';\n }\n break;\n }\n\n case 'task_completed': {\n const a = session.agents.get(event.agentId);\n if (a) {\n a.currentTask = null;\n a.status = event.result === 'success' ? 'completed' : 'failed';\n }\n break;\n }\n\n case 'message_sent': {\n const edgeId = `msg-${event.fromId}-${event.toId}-${Date.now()}`;\n session.edges.push({\n id: edgeId,\n source: event.fromId,\n target: event.toId,\n edgeType: 'message',\n active: true,\n label: event.summary,\n });\n // Remove transient message edges after 5 seconds\n setTimeout(() => {\n session.edges = session.edges.filter((e) => e.id !== edgeId);\n }, 5_000);\n break;\n }\n\n case 'mention_created':\n case 'mention_resolved':\n // Logged but don't mutate the agent graph.\n break;\n\n case 'cost_update': {\n session.totalCost = event.totalCost;\n break;\n }\n }\n }\n\n // -----------------------------------------------------------------------\n // Private — flush debounced events\n // -----------------------------------------------------------------------\n\n private flushEvents(sessionId: string): void {\n const events = this.pendingEvents.get(sessionId);\n const session = this.sessions.get(sessionId);\n if (!events || !session || events.length === 0) return;\n\n const delta: SessionDelta = {\n type: 'session-delta',\n sessionId,\n displayName: session.displayName,\n timestamp: Date.now(),\n events: [...events],\n };\n\n this.emit('broadcast', JSON.stringify(delta));\n this.pendingEvents.set(sessionId, []);\n }\n}\n","import WebSocket from 'ws';\nimport type { AgentEvent, RegisterMessage, SessionEventMessage, UnregisterMessage } from '../types/dashboard-events.js';\nimport { eventBus } from '../orchestrator/event-bus.js';\nimport { logger } from '../utils/logger.js';\n\nexport class DashboardClient {\n private ws: WebSocket | null = null;\n private sessionId: string;\n private projectName: string;\n private projectPath: string;\n\n constructor(sessionId: string, projectName: string, projectPath: string) {\n this.sessionId = sessionId;\n this.projectName = projectName;\n this.projectPath = projectPath;\n }\n\n connect(port: number): void {\n this.ws = new WebSocket(`ws://127.0.0.1:${port}`);\n\n this.ws.on('open', () => {\n logger.info(`Connected to dashboard as client (session: ${this.sessionId})`);\n // Register this session\n const msg: RegisterMessage = {\n type: 'register',\n sessionId: this.sessionId,\n projectPath: this.projectPath,\n projectName: this.projectName,\n };\n this.ws!.send(JSON.stringify(msg));\n\n // Forward local events to the dashboard server\n eventBus.on('agent_event', (event: AgentEvent) => {\n if (this.ws?.readyState === WebSocket.OPEN) {\n const sessionMsg: SessionEventMessage = {\n type: 'session-event',\n sessionId: this.sessionId,\n event,\n };\n this.ws.send(JSON.stringify(sessionMsg));\n }\n });\n });\n\n this.ws.on('error', (err) => {\n logger.warn(`Dashboard client error: ${err.message}`);\n });\n\n this.ws.on('close', () => {\n logger.info('Dashboard client disconnected');\n });\n }\n\n disconnect(): void {\n if (this.ws && this.ws.readyState === WebSocket.OPEN) {\n const msg: UnregisterMessage = {\n type: 'unregister',\n sessionId: this.sessionId,\n };\n this.ws.send(JSON.stringify(msg));\n this.ws.close();\n }\n this.ws = null;\n }\n}\n"],"mappings":"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AAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;A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","names":["uuidv4","uuidv4","uuidv4","uuidv4","uuidv4","uuidv4","uuidv4","uuidv4","uuidv4","z","z","result","z","z","z","uuidv4","DEPARTMENT_KEYWORDS","uuidv4","z","z","z","z","z","z","z","getDb","z","z","z","z","z","z","z","readFileSync","existsSync","join","join","join","existsSync","readFileSync","mkdirSync","writeFileSync","join","join","mkdirSync","writeFileSync","readFileSync","writeFileSync","join","join","writeFileSync","z","z","z","z","z","WebSocket","EventEmitter","EventEmitter","WebSocket"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/server.ts","../src/tools/start-meeting.ts","../src/orchestrator/orchestrator.ts","../src/storage/agent-store.ts","../src/storage/meeting-store.ts","../src/storage/worker-store.ts","../src/storage/mention-store.ts","../src/storage/minutes-store.ts","../src/storage/task-store.ts","../src/types/agent.ts","../src/types/meeting.ts","../src/agents/departments.ts","../src/orchestrator/event-bus.ts","../src/utils/logger.ts","../src/orchestrator/leader-pool.ts","../src/agents/leader-prompts.ts","../src/agents/tiers.ts","../src/agents/worker-prompts.ts","../src/agents/agent-factory.ts","../src/agents/claude-invoker.ts","../src/orchestrator/meeting-runner.ts","../src/agents/project-analyzer.ts","../src/tools/get-meeting-status.ts","../src/tools/get-minutes.ts","../src/tools/compact-minutes.ts","../src/meeting/compactor.ts","../src/tools/execute-tasks.ts","../src/orchestrator/worker-manager.ts","../src/tools/get-agent-tree.ts","../src/tools/respond-to-mention.ts","../src/tools/get-mentions.ts","../src/tools/cancel-meeting.ts","../src/tools/list-meetings.ts","../src/tools/get-task-report.ts","../src/tools/create-capability.ts","../src/extension/capability-registry.ts","../src/utils/config.ts","../src/extension/generator.ts","../src/extension/guide-updater.ts","../src/extension/extension-manager.ts","../src/tools/get-cost-summary.ts","../src/utils/cost-tracker.ts","../src/tools/chain-meeting.ts","../src/dashboard/server.ts","../src/dashboard/html.ts","../src/dashboard/state-bridge.ts","../src/dashboard/client.ts"],"sourcesContent":["import { randomUUID } from 'node:crypto';\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';\nimport { createServer } from './server.js';\nimport { ensureDataDirs } from './utils/config.js';\nimport { startDashboard } from './dashboard/server.js';\n\nasync function main() {\n ensureDataDirs();\n\n // Only start dashboard if NOT running as a bare subprocess\n // (bare mode = spawned by claude-invoker, should not start dashboard)\n const isBareSubprocess = process.env['CLAUDE_CODE_SIMPLE'] === '1';\n\n if (!isBareSubprocess) {\n const sessionId = randomUUID();\n const projectPath = process.cwd();\n const projectName = projectPath.split('/').pop() ?? 'unknown';\n startDashboard({ sessionId, projectPath, projectName }).catch(() => {});\n }\n\n const server = createServer();\n const transport = new StdioServerTransport();\n await server.connect(transport);\n}\n\nmain().catch((error) => {\n console.error('Fatal error:', error);\n process.exit(1);\n});\n","import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport {\n startMeetingSchema,\n startMeetingHandler,\n getMeetingStatusSchema,\n getMeetingStatusHandler,\n getMinutesSchema,\n getMinutesHandler,\n compactMinutesSchema,\n compactMinutesHandler,\n executeTasksSchema,\n executeTasksHandler,\n getAgentTreeHandler,\n respondToMentionSchema,\n respondToMentionHandler,\n getMentionsSchema,\n getMentionsHandler,\n cancelMeetingSchema,\n cancelMeetingHandler,\n listMeetingsSchema,\n listMeetingsHandler,\n getTaskReportSchema,\n getTaskReportHandler,\n createCapabilitySchema,\n createCapabilityHandler,\n getCostSummarySchema,\n getCostSummaryHandler,\n chainMeetingSchema,\n chainMeetingHandler,\n} from './tools/index.js';\n\nexport function createServer(): McpServer {\n const server = new McpServer({\n name: 'open-coleslaw',\n version: '0.1.0',\n });\n\n // 1. start-meeting\n server.tool(\n 'start-meeting',\n 'Start a new multi-agent meeting on a topic with agenda items',\n startMeetingSchema,\n startMeetingHandler,\n );\n\n // 2. get-meeting-status\n server.tool(\n 'get-meeting-status',\n 'Get the status of a specific meeting or all active meetings',\n getMeetingStatusSchema,\n getMeetingStatusHandler,\n );\n\n // 3. get-minutes\n server.tool(\n 'get-minutes',\n 'Retrieve meeting minutes in full, summary, or tasks-only format',\n getMinutesSchema,\n getMinutesHandler,\n );\n\n // 4. compact-minutes\n server.tool(\n 'compact-minutes',\n 'Compact meeting minutes into a structured, department-assigned task list',\n compactMinutesSchema,\n compactMinutesHandler,\n );\n\n // 5. execute-tasks\n server.tool(\n 'execute-tasks',\n 'Execute tasks from compacted minutes by spawning workers per department',\n executeTasksSchema,\n executeTasksHandler,\n );\n\n // 6. get-agent-tree\n server.tool(\n 'get-agent-tree',\n 'Return the full agent hierarchy tree',\n getAgentTreeHandler,\n );\n\n // 7. respond-to-mention\n server.tool(\n 'respond-to-mention',\n 'Respond to a pending @mention with a decision',\n respondToMentionSchema,\n respondToMentionHandler,\n );\n\n // 8. get-mentions\n server.tool(\n 'get-mentions',\n 'List @mentions filtered by status and/or meeting',\n getMentionsSchema,\n getMentionsHandler,\n );\n\n // 9. cancel-meeting\n server.tool(\n 'cancel-meeting',\n 'Cancel an active meeting and clean up its agents and workers',\n cancelMeetingSchema,\n cancelMeetingHandler,\n );\n\n // 10. list-meetings\n server.tool(\n 'list-meetings',\n 'List meetings with optional status filter and pagination',\n listMeetingsSchema,\n listMeetingsHandler,\n );\n\n // 11. get-task-report\n server.tool(\n 'get-task-report',\n 'Generate a task execution report for a meeting with per-department breakdown',\n getTaskReportSchema,\n getTaskReportHandler,\n );\n\n // 12. create-capability\n server.tool(\n 'create-capability',\n 'Create a new extension capability (hook, skill, command, asset, or loop)',\n createCapabilitySchema,\n createCapabilityHandler,\n );\n\n // 13. get-cost-summary\n server.tool(\n 'get-cost-summary',\n 'Get cost summary for a specific meeting or overall across all meetings',\n getCostSummarySchema,\n getCostSummaryHandler,\n );\n\n // 14. chain-meeting\n server.tool(\n 'chain-meeting',\n 'Start a new meeting chained from a previous meeting, using its minutes as context',\n chainMeetingSchema,\n chainMeetingHandler,\n );\n\n return server;\n}\n","import { z } from 'zod';\nimport { Orchestrator } from '../orchestrator/orchestrator.js';\nimport type { Department } from '../types/index.js';\n\nexport const startMeetingSchema = {\n topic: z.string().describe('Meeting topic'),\n agenda: z.array(z.string()).describe('Agenda items'),\n departments: z\n .array(z.string())\n .optional()\n .describe('Specific departments to invite'),\n};\n\nexport async function startMeetingHandler({\n topic,\n agenda,\n departments,\n}: {\n topic: string;\n agenda: string[];\n departments?: string[];\n}): Promise<{ content: { type: 'text'; text: string }[]; isError?: boolean }> {\n try {\n const orchestrator = new Orchestrator();\n const meetingId = await orchestrator.startMeeting({\n topic,\n agenda,\n departments: departments as Department[] | undefined,\n });\n\n const result = {\n meetingId,\n status: 'started',\n topic,\n agenda,\n departments: departments ?? orchestrator.selectLeaders(topic, agenda),\n };\n\n return {\n content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],\n };\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n return {\n content: [\n { type: 'text', text: JSON.stringify({ error: message }, null, 2) },\n ],\n isError: true,\n };\n }\n}\n","import { v4 as uuidv4 } from 'uuid';\nimport type {\n Department,\n Meeting,\n MentionRecord,\n AgentNode,\n} from '../types/index.js';\nimport {\n createMeeting,\n updateMeeting,\n getMeeting,\n listMeetings,\n listPendingMentions,\n getAgentTree,\n getMinutesByMeeting,\n} from '../storage/index.js';\nimport type { AgentTreeNode } from '../storage/index.js';\nimport { LeaderPool } from './leader-pool.js';\nimport { MeetingRunner } from './meeting-runner.js';\nimport { eventBus } from './event-bus.js';\nimport { logger } from '../utils/logger.js';\nimport { analyzeProject, formatProjectContext } from '../agents/project-analyzer.js';\n\n// ---------------------------------------------------------------------------\n// Keyword maps for leader selection heuristics\n// ---------------------------------------------------------------------------\n\nconst DEPARTMENT_KEYWORDS: Record<Department, string[]> = {\n architecture: [\n 'architecture', 'design', 'schema', 'api', 'data model', 'module',\n 'interface', 'contract', 'coupling', 'dependency graph', 'adr',\n 'system design', 'blueprint', 'data flow',\n ],\n engineering: [\n 'code', 'implement', 'build', 'feature', 'bug', 'fix', 'refactor',\n 'develop', 'function', 'class', 'module', 'write', 'create',\n 'modify', 'update', 'delete', 'crud', 'endpoint', 'migration',\n ],\n qa: [\n 'test', 'quality', 'security', 'performance', 'audit', 'coverage',\n 'regression', 'benchmark', 'vulnerability', 'pen test', 'lint',\n 'assertion', 'e2e', 'integration test', 'unit test',\n ],\n product: [\n 'requirements', 'user', 'story', 'priority', 'acceptance criteria',\n 'user flow', 'stakeholder', 'roadmap', 'scope', 'use case',\n 'persona', 'mvp', 'specification',\n ],\n research: [\n 'research', 'explore', 'investigate', 'search', 'analyze', 'find',\n 'discover', 'benchmark', 'compare', 'survey', 'documentation',\n 'reference', 'existing code',\n ],\n};\n\n// ---------------------------------------------------------------------------\n// StartMeeting options\n// ---------------------------------------------------------------------------\n\nexport interface StartMeetingOptions {\n topic: string;\n agenda: string[];\n departments?: Department[];\n}\n\n// ---------------------------------------------------------------------------\n// Orchestrator status\n// ---------------------------------------------------------------------------\n\nexport interface OrchestratorStatus {\n activeMeetings: Meeting[];\n pendingMentions: MentionRecord[];\n agentTree: AgentTreeNode | null;\n}\n\n// ---------------------------------------------------------------------------\n// Orchestrator\n// ---------------------------------------------------------------------------\n\nexport class Orchestrator {\n private readonly leaderPool = new LeaderPool();\n\n /**\n * Internal ID for the orchestrator \"agent\". Used as the meeting initiator\n * and as the root of the agent tree.\n */\n private readonly orchestratorId: string;\n\n constructor(orchestratorId?: string) {\n this.orchestratorId = orchestratorId ?? 'orchestrator-root';\n }\n\n // ---- leader selection ---------------------------------------------------\n\n /**\n * Analyse a topic and agenda to determine which department leaders should\n * be convened for a meeting.\n *\n * Uses keyword-based heuristics:\n * - Matches topic + agenda text against per-department keyword lists.\n * - Scores each department by the number of keyword hits.\n * - Selects departments with at least one hit.\n * - Falls back to engineering + architecture for complex topics (multiple\n * agenda items) or engineering alone for simple ones.\n */\n selectLeaders(topic: string, agenda: string[]): Department[] {\n const corpus = [topic, ...agenda].join(' ').toLowerCase();\n\n const scores = new Map<Department, number>();\n\n for (const [dept, keywords] of Object.entries(DEPARTMENT_KEYWORDS) as [Department, string[]][]) {\n let score = 0;\n for (const kw of keywords) {\n if (corpus.includes(kw)) {\n score++;\n }\n }\n if (score > 0) {\n scores.set(dept, score);\n }\n }\n\n if (scores.size === 0) {\n // Fallback: complex topics (3+ agenda items) get architecture + engineering;\n // simple ones get engineering only.\n if (agenda.length >= 3) {\n logger.debug('No keyword matches; defaulting to architecture + engineering (complex topic)', {\n meetingId: topic,\n });\n return ['architecture', 'engineering'];\n }\n logger.debug('No keyword matches; defaulting to engineering only (simple topic)', {\n meetingId: topic,\n });\n return ['engineering'];\n }\n\n // Sort by score descending and take all with hits\n const selected = [...scores.entries()]\n .sort((a, b) => b[1] - a[1])\n .map(([dept]) => dept);\n\n logger.debug(`Selected departments: ${selected.join(', ')}`, { meetingId: topic });\n\n return selected;\n }\n\n // ---- start meeting ------------------------------------------------------\n\n /**\n * Start a new meeting.\n *\n * 1. Selects departments (if not provided).\n * 2. Creates the meeting record in SQLite.\n * 3. Spawns leaders via the LeaderPool.\n * 4. Runs the MeetingRunner lifecycle (opening -> discussion -> synthesis -> minutes).\n * 5. Deactivates leaders after completion.\n *\n * Returns the meeting ID.\n */\n async startMeeting(opts: StartMeetingOptions & { previousMeetingId?: string | null }): Promise<string> {\n const { topic, agenda } = opts;\n const departments = opts.departments ?? this.selectLeaders(topic, agenda);\n\n logger.info(`Starting meeting: \"${topic}\" with departments: [${departments.join(', ')}]`);\n\n // 0. Analyse the current working directory for project context\n let projectContext: string | undefined;\n try {\n const analysis = await analyzeProject(process.cwd());\n projectContext = formatProjectContext(analysis);\n logger.debug('Project analysis complete', { meetingId: topic });\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n logger.warn(`Project analysis failed (proceeding without context): ${msg}`);\n }\n\n // 1. Create the meeting record\n const meetingId = uuidv4();\n const meeting = createMeeting({\n id: meetingId,\n topic,\n agenda,\n participantIds: [], // Will be filled in after leader spawning\n initiatedBy: this.orchestratorId,\n status: 'convening',\n phase: 'convening',\n startedAt: Date.now(),\n previousMeetingId: opts.previousMeetingId ?? null,\n });\n\n // 2. Spawn leaders\n const leaders: AgentNode[] = [];\n for (const dept of departments) {\n const leader = this.leaderPool.spawnLeader(dept, meetingId);\n leaders.push(leader);\n }\n\n // Update meeting with participant IDs\n updateMeeting(meetingId, {\n participantIds: leaders.map((l) => l.id),\n });\n\n // 3. Run the meeting (with project context for leader prompts)\n const runner = new MeetingRunner(meetingId, leaders, projectContext);\n\n try {\n await runner.run();\n } finally {\n // 4. Deactivate leaders regardless of success/failure\n for (const leader of leaders) {\n this.leaderPool.deactivateLeader(leader.id);\n }\n }\n\n return meetingId;\n }\n\n // ---- chain meeting -------------------------------------------------------\n\n /**\n * Chain a new meeting from the output of a previous meeting.\n *\n * Loads minutes from the previous meeting and includes them as context for\n * the new meeting topic. The new meeting's `previousMeetingId` is set for\n * traceability.\n */\n async chainMeeting(opts: {\n previousMeetingId: string;\n topic: string;\n agenda: string[];\n departments?: Department[];\n }): Promise<string> {\n const previousMeeting = getMeeting(opts.previousMeetingId);\n if (!previousMeeting) {\n throw new Error(`Previous meeting not found: ${opts.previousMeetingId}`);\n }\n\n const previousMinutes = getMinutesByMeeting(opts.previousMeetingId);\n if (!previousMinutes) {\n throw new Error(`No minutes found for previous meeting: ${opts.previousMeetingId}`);\n }\n\n // Prepend the previous meeting context to the topic\n const contextPrefix =\n `[Chained from meeting \"${previousMeeting.topic}\" (${opts.previousMeetingId})]\\n\\n` +\n `--- Previous Meeting Minutes ---\\n${previousMinutes.content}\\n--- End Previous Minutes ---\\n\\n`;\n\n const enrichedTopic = contextPrefix + opts.topic;\n\n logger.info(\n `Chaining meeting from \"${previousMeeting.topic}\" -> \"${opts.topic}\"`,\n { meetingId: opts.previousMeetingId },\n );\n\n return this.startMeeting({\n topic: enrichedTopic,\n agenda: opts.agenda,\n departments: opts.departments,\n previousMeetingId: opts.previousMeetingId,\n });\n }\n\n // ---- status -------------------------------------------------------------\n\n /**\n * Return a summary of all active meetings, pending @mentions, and the\n * current agent tree.\n */\n getStatus(): OrchestratorStatus {\n // Active meetings: anything not completed/cancelled/failed\n const allMeetings = listMeetings();\n const activeMeetings = allMeetings.filter(\n (m) => !['completed', 'cancelled', 'failed', 'reported', 'compacted'].includes(m.status),\n );\n\n // Pending @mentions across all meetings\n const pendingMentions = listPendingMentions();\n\n // Agent tree rooted at the orchestrator (may be null if no agents yet)\n const agentTree = getAgentTree(this.orchestratorId);\n\n return {\n activeMeetings,\n pendingMentions,\n agentTree,\n };\n }\n\n // ---- accessors ----------------------------------------------------------\n\n /** The leader pool used by this orchestrator instance. */\n getLeaderPool(): LeaderPool {\n return this.leaderPool;\n }\n\n /** The orchestrator's agent ID. */\n getId(): string {\n return this.orchestratorId;\n }\n}\n","import { v4 as uuidv4 } from 'uuid';\nimport { getDb } from './db.js';\nimport type { AgentNode, AgentTier, AgentStatus, Department } from '../types/index.js';\n\ninterface AgentRow {\n id: string;\n tier: string;\n role: string;\n department: string;\n parent_id: string | null;\n meeting_id: string | null;\n status: string;\n current_task: string | null;\n session_id: string | null;\n spawned_at: number;\n completed_at: number | null;\n cost_usd: number;\n}\n\nfunction rowToAgent(row: AgentRow): AgentNode {\n return {\n id: row.id,\n tier: row.tier as AgentTier,\n role: row.role,\n department: row.department as Department,\n parentId: row.parent_id,\n meetingId: row.meeting_id,\n status: row.status as AgentStatus,\n currentTask: row.current_task,\n sessionId: row.session_id,\n spawnedAt: row.spawned_at,\n completedAt: row.completed_at,\n costUsd: row.cost_usd,\n };\n}\n\nexport function createAgent(\n agent: Omit<AgentNode, 'id' | 'spawnedAt' | 'completedAt' | 'costUsd'> & {\n id?: string;\n spawnedAt?: number;\n completedAt?: number | null;\n costUsd?: number;\n }\n): AgentNode {\n const db = getDb();\n const id = agent.id ?? uuidv4();\n const spawnedAt = agent.spawnedAt ?? Date.now();\n const completedAt = agent.completedAt ?? null;\n const costUsd = agent.costUsd ?? 0;\n\n db.prepare(\n `INSERT INTO agents (id, tier, role, department, parent_id, meeting_id, status, current_task, session_id, spawned_at, completed_at, cost_usd)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`\n ).run(\n id,\n agent.tier,\n agent.role,\n agent.department,\n agent.parentId,\n agent.meetingId,\n agent.status,\n agent.currentTask,\n agent.sessionId,\n spawnedAt,\n completedAt,\n costUsd\n );\n\n return {\n id,\n tier: agent.tier,\n role: agent.role,\n department: agent.department,\n parentId: agent.parentId,\n meetingId: agent.meetingId,\n status: agent.status,\n currentTask: agent.currentTask,\n sessionId: agent.sessionId,\n spawnedAt,\n completedAt,\n costUsd,\n };\n}\n\nexport function getAgent(id: string): AgentNode | null {\n const db = getDb();\n const row = db.prepare('SELECT * FROM agents WHERE id = ?').get(id) as AgentRow | undefined;\n return row ? rowToAgent(row) : null;\n}\n\nexport function updateAgent(\n id: string,\n updates: Partial<Omit<AgentNode, 'id'>>\n): AgentNode | null {\n const db = getDb();\n const existing = getAgent(id);\n if (!existing) return null;\n\n const fields: string[] = [];\n const values: unknown[] = [];\n\n if (updates.tier !== undefined) { fields.push('tier = ?'); values.push(updates.tier); }\n if (updates.role !== undefined) { fields.push('role = ?'); values.push(updates.role); }\n if (updates.department !== undefined) { fields.push('department = ?'); values.push(updates.department); }\n if (updates.parentId !== undefined) { fields.push('parent_id = ?'); values.push(updates.parentId); }\n if (updates.meetingId !== undefined) { fields.push('meeting_id = ?'); values.push(updates.meetingId); }\n if (updates.status !== undefined) { fields.push('status = ?'); values.push(updates.status); }\n if (updates.currentTask !== undefined) { fields.push('current_task = ?'); values.push(updates.currentTask); }\n if (updates.sessionId !== undefined) { fields.push('session_id = ?'); values.push(updates.sessionId); }\n if (updates.spawnedAt !== undefined) { fields.push('spawned_at = ?'); values.push(updates.spawnedAt); }\n if (updates.completedAt !== undefined) { fields.push('completed_at = ?'); values.push(updates.completedAt); }\n if (updates.costUsd !== undefined) { fields.push('cost_usd = ?'); values.push(updates.costUsd); }\n\n if (fields.length === 0) return existing;\n\n values.push(id);\n db.prepare(`UPDATE agents SET ${fields.join(', ')} WHERE id = ?`).run(...values);\n\n return getAgent(id);\n}\n\nexport function listAgentsByMeeting(meetingId: string): AgentNode[] {\n const db = getDb();\n const rows = db\n .prepare('SELECT * FROM agents WHERE meeting_id = ?')\n .all(meetingId) as AgentRow[];\n return rows.map(rowToAgent);\n}\n\nexport function listAgentsByParent(parentId: string): AgentNode[] {\n const db = getDb();\n const rows = db\n .prepare('SELECT * FROM agents WHERE parent_id = ?')\n .all(parentId) as AgentRow[];\n return rows.map(rowToAgent);\n}\n\nexport interface AgentTreeNode extends AgentNode {\n children: AgentTreeNode[];\n}\n\nexport function getAgentTree(rootId: string): AgentTreeNode | null {\n const agent = getAgent(rootId);\n if (!agent) return null;\n\n const children = listAgentsByParent(rootId);\n const treeNode: AgentTreeNode = {\n ...agent,\n children: children\n .map((child) => getAgentTree(child.id))\n .filter((node): node is AgentTreeNode => node !== null),\n };\n\n return treeNode;\n}\n","import { v4 as uuidv4 } from 'uuid';\nimport { getDb } from './db.js';\nimport type { Meeting, MeetingStatus, MeetingPhase } from '../types/index.js';\n\ninterface MeetingRow {\n id: string;\n topic: string;\n agenda: string;\n participant_ids: string;\n status: string;\n phase: string;\n started_at: number | null;\n completed_at: number | null;\n initiated_by: string;\n previous_meeting_id?: string | null;\n}\n\n/** Ensure the previous_meeting_id column exists (backward-compat migration). */\nfunction ensurePreviousMeetingIdColumn(): void {\n const db = getDb();\n // PRAGMA table_info returns rows for each column; check if the column exists.\n const cols = db.prepare(\"PRAGMA table_info('meetings')\").all() as Array<{ name: string }>;\n const hasColumn = cols.some((c) => c.name === 'previous_meeting_id');\n if (!hasColumn) {\n db.exec('ALTER TABLE meetings ADD COLUMN previous_meeting_id TEXT DEFAULT NULL');\n }\n}\n\nlet columnChecked = false;\n\nfunction rowToMeeting(row: MeetingRow): Meeting {\n return {\n id: row.id,\n topic: row.topic,\n agenda: JSON.parse(row.agenda) as string[],\n participantIds: JSON.parse(row.participant_ids) as string[],\n status: row.status as MeetingStatus,\n phase: row.phase as MeetingPhase,\n startedAt: row.started_at,\n completedAt: row.completed_at,\n initiatedBy: row.initiated_by,\n previousMeetingId: row.previous_meeting_id ?? null,\n };\n}\n\nexport function createMeeting(\n meeting: Omit<Meeting, 'id' | 'status' | 'phase' | 'startedAt' | 'completedAt' | 'previousMeetingId'> & {\n id?: string;\n status?: MeetingStatus;\n phase?: MeetingPhase;\n startedAt?: number | null;\n completedAt?: number | null;\n previousMeetingId?: string | null;\n }\n): Meeting {\n if (!columnChecked) {\n ensurePreviousMeetingIdColumn();\n columnChecked = true;\n }\n\n const db = getDb();\n const id = meeting.id ?? uuidv4();\n const status = meeting.status ?? 'pending';\n const phase = meeting.phase ?? 'orchestrator-phase';\n const startedAt = meeting.startedAt ?? null;\n const completedAt = meeting.completedAt ?? null;\n const previousMeetingId = meeting.previousMeetingId ?? null;\n\n db.prepare(\n `INSERT INTO meetings (id, topic, agenda, participant_ids, status, phase, started_at, completed_at, initiated_by, previous_meeting_id)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`\n ).run(\n id,\n meeting.topic,\n JSON.stringify(meeting.agenda),\n JSON.stringify(meeting.participantIds),\n status,\n phase,\n startedAt,\n completedAt,\n meeting.initiatedBy,\n previousMeetingId\n );\n\n return {\n id,\n topic: meeting.topic,\n agenda: meeting.agenda,\n participantIds: meeting.participantIds,\n status,\n phase,\n startedAt,\n completedAt,\n initiatedBy: meeting.initiatedBy,\n previousMeetingId,\n };\n}\n\nexport function getMeeting(id: string): Meeting | null {\n if (!columnChecked) {\n ensurePreviousMeetingIdColumn();\n columnChecked = true;\n }\n\n const db = getDb();\n const row = db.prepare('SELECT * FROM meetings WHERE id = ?').get(id) as MeetingRow | undefined;\n return row ? rowToMeeting(row) : null;\n}\n\nexport function updateMeeting(\n id: string,\n updates: Partial<Omit<Meeting, 'id'>>\n): Meeting | null {\n const db = getDb();\n const existing = getMeeting(id);\n if (!existing) return null;\n\n const fields: string[] = [];\n const values: unknown[] = [];\n\n if (updates.topic !== undefined) { fields.push('topic = ?'); values.push(updates.topic); }\n if (updates.agenda !== undefined) { fields.push('agenda = ?'); values.push(JSON.stringify(updates.agenda)); }\n if (updates.participantIds !== undefined) { fields.push('participant_ids = ?'); values.push(JSON.stringify(updates.participantIds)); }\n if (updates.status !== undefined) { fields.push('status = ?'); values.push(updates.status); }\n if (updates.phase !== undefined) { fields.push('phase = ?'); values.push(updates.phase); }\n if (updates.startedAt !== undefined) { fields.push('started_at = ?'); values.push(updates.startedAt); }\n if (updates.completedAt !== undefined) { fields.push('completed_at = ?'); values.push(updates.completedAt); }\n if (updates.initiatedBy !== undefined) { fields.push('initiated_by = ?'); values.push(updates.initiatedBy); }\n if (updates.previousMeetingId !== undefined) { fields.push('previous_meeting_id = ?'); values.push(updates.previousMeetingId); }\n\n if (fields.length === 0) return existing;\n\n values.push(id);\n db.prepare(`UPDATE meetings SET ${fields.join(', ')} WHERE id = ?`).run(...values);\n\n return getMeeting(id);\n}\n\nexport function listMeetings(statusFilter?: MeetingStatus): Meeting[] {\n if (!columnChecked) {\n ensurePreviousMeetingIdColumn();\n columnChecked = true;\n }\n\n const db = getDb();\n let rows: MeetingRow[];\n\n if (statusFilter) {\n rows = db\n .prepare('SELECT * FROM meetings WHERE status = ? ORDER BY started_at DESC')\n .all(statusFilter) as MeetingRow[];\n } else {\n rows = db\n .prepare('SELECT * FROM meetings ORDER BY started_at DESC')\n .all() as MeetingRow[];\n }\n\n return rows.map(rowToMeeting);\n}\n","import { v4 as uuidv4 } from 'uuid';\nimport { getDb } from './db.js';\nimport type { WorkerRecord, WorkerStatus, TaskType } from '../types/index.js';\n\ninterface WorkerRow {\n id: string;\n leader_id: string;\n meeting_id: string;\n task_description: string;\n task_type: string | null;\n status: string;\n input_context: string | null;\n output_result: string | null;\n error_message: string | null;\n dependencies: string;\n spawned_at: number;\n completed_at: number | null;\n cost_usd: number;\n}\n\nfunction rowToWorker(row: WorkerRow): WorkerRecord {\n return {\n id: row.id,\n leaderId: row.leader_id,\n meetingId: row.meeting_id,\n taskDescription: row.task_description,\n taskType: row.task_type as TaskType | null,\n status: row.status as WorkerStatus,\n inputContext: row.input_context,\n outputResult: row.output_result,\n errorMessage: row.error_message,\n dependencies: JSON.parse(row.dependencies) as string[],\n spawnedAt: row.spawned_at,\n completedAt: row.completed_at,\n costUsd: row.cost_usd,\n };\n}\n\nexport function createWorker(\n worker: Omit<WorkerRecord, 'id' | 'status' | 'spawnedAt' | 'completedAt' | 'costUsd'> & {\n id?: string;\n status?: WorkerStatus;\n spawnedAt?: number;\n completedAt?: number | null;\n costUsd?: number;\n }\n): WorkerRecord {\n const db = getDb();\n const id = worker.id ?? uuidv4();\n const status = worker.status ?? 'pending';\n const spawnedAt = worker.spawnedAt ?? Date.now();\n const completedAt = worker.completedAt ?? null;\n const costUsd = worker.costUsd ?? 0;\n\n db.prepare(\n `INSERT INTO workers (id, leader_id, meeting_id, task_description, task_type, status, input_context, output_result, error_message, dependencies, spawned_at, completed_at, cost_usd)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`\n ).run(\n id,\n worker.leaderId,\n worker.meetingId,\n worker.taskDescription,\n worker.taskType,\n status,\n worker.inputContext,\n worker.outputResult,\n worker.errorMessage,\n JSON.stringify(worker.dependencies),\n spawnedAt,\n completedAt,\n costUsd\n );\n\n return {\n id,\n leaderId: worker.leaderId,\n meetingId: worker.meetingId,\n taskDescription: worker.taskDescription,\n taskType: worker.taskType,\n status,\n inputContext: worker.inputContext,\n outputResult: worker.outputResult,\n errorMessage: worker.errorMessage,\n dependencies: worker.dependencies,\n spawnedAt,\n completedAt,\n costUsd,\n };\n}\n\nexport function getWorker(id: string): WorkerRecord | null {\n const db = getDb();\n const row = db.prepare('SELECT * FROM workers WHERE id = ?').get(id) as WorkerRow | undefined;\n return row ? rowToWorker(row) : null;\n}\n\nexport function updateWorker(\n id: string,\n updates: Partial<Omit<WorkerRecord, 'id'>>\n): WorkerRecord | null {\n const db = getDb();\n const existing = getWorker(id);\n if (!existing) return null;\n\n const fields: string[] = [];\n const values: unknown[] = [];\n\n if (updates.leaderId !== undefined) { fields.push('leader_id = ?'); values.push(updates.leaderId); }\n if (updates.meetingId !== undefined) { fields.push('meeting_id = ?'); values.push(updates.meetingId); }\n if (updates.taskDescription !== undefined) { fields.push('task_description = ?'); values.push(updates.taskDescription); }\n if (updates.taskType !== undefined) { fields.push('task_type = ?'); values.push(updates.taskType); }\n if (updates.status !== undefined) { fields.push('status = ?'); values.push(updates.status); }\n if (updates.inputContext !== undefined) { fields.push('input_context = ?'); values.push(updates.inputContext); }\n if (updates.outputResult !== undefined) { fields.push('output_result = ?'); values.push(updates.outputResult); }\n if (updates.errorMessage !== undefined) { fields.push('error_message = ?'); values.push(updates.errorMessage); }\n if (updates.dependencies !== undefined) { fields.push('dependencies = ?'); values.push(JSON.stringify(updates.dependencies)); }\n if (updates.spawnedAt !== undefined) { fields.push('spawned_at = ?'); values.push(updates.spawnedAt); }\n if (updates.completedAt !== undefined) { fields.push('completed_at = ?'); values.push(updates.completedAt); }\n if (updates.costUsd !== undefined) { fields.push('cost_usd = ?'); values.push(updates.costUsd); }\n\n if (fields.length === 0) return existing;\n\n values.push(id);\n db.prepare(`UPDATE workers SET ${fields.join(', ')} WHERE id = ?`).run(...values);\n\n return getWorker(id);\n}\n\nexport function listWorkersByLeader(leaderId: string): WorkerRecord[] {\n const db = getDb();\n const rows = db\n .prepare('SELECT * FROM workers WHERE leader_id = ? ORDER BY spawned_at ASC')\n .all(leaderId) as WorkerRow[];\n return rows.map(rowToWorker);\n}\n","import { v4 as uuidv4 } from 'uuid';\nimport { getDb } from './db.js';\nimport type { MentionRecord, MentionUrgency, MentionStatus, MentionOption } from '../types/index.js';\n\ninterface MentionRow {\n id: string;\n meeting_id: string;\n agenda_item: string | null;\n summary: string;\n options: string;\n urgency: string;\n status: string;\n user_decision: string | null;\n user_reasoning: string | null;\n created_at: number;\n resolved_at: number | null;\n}\n\nfunction rowToMention(row: MentionRow): MentionRecord {\n return {\n id: row.id,\n meetingId: row.meeting_id,\n agendaItem: row.agenda_item,\n summary: row.summary,\n options: JSON.parse(row.options) as MentionOption[],\n urgency: row.urgency as MentionUrgency,\n status: row.status as MentionStatus,\n userDecision: row.user_decision,\n userReasoning: row.user_reasoning,\n createdAt: row.created_at,\n resolvedAt: row.resolved_at,\n };\n}\n\nexport function createMention(\n mention: Omit<MentionRecord, 'id' | 'status' | 'createdAt' | 'resolvedAt'> & {\n id?: string;\n status?: MentionStatus;\n createdAt?: number;\n resolvedAt?: number | null;\n }\n): MentionRecord {\n const db = getDb();\n const id = mention.id ?? uuidv4();\n const status = mention.status ?? 'pending';\n const createdAt = mention.createdAt ?? Date.now();\n const resolvedAt = mention.resolvedAt ?? null;\n\n db.prepare(\n `INSERT INTO mentions (id, meeting_id, agenda_item, summary, options, urgency, status, user_decision, user_reasoning, created_at, resolved_at)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`\n ).run(\n id,\n mention.meetingId,\n mention.agendaItem,\n mention.summary,\n JSON.stringify(mention.options),\n mention.urgency,\n status,\n mention.userDecision,\n mention.userReasoning,\n createdAt,\n resolvedAt\n );\n\n return {\n id,\n meetingId: mention.meetingId,\n agendaItem: mention.agendaItem,\n summary: mention.summary,\n options: mention.options,\n urgency: mention.urgency,\n status,\n userDecision: mention.userDecision,\n userReasoning: mention.userReasoning,\n createdAt,\n resolvedAt,\n };\n}\n\nexport function getMention(id: string): MentionRecord | null {\n const db = getDb();\n const row = db.prepare('SELECT * FROM mentions WHERE id = ?').get(id) as MentionRow | undefined;\n return row ? rowToMention(row) : null;\n}\n\nexport function updateMention(\n id: string,\n updates: Partial<Omit<MentionRecord, 'id'>>\n): MentionRecord | null {\n const db = getDb();\n const existing = getMention(id);\n if (!existing) return null;\n\n const fields: string[] = [];\n const values: unknown[] = [];\n\n if (updates.meetingId !== undefined) { fields.push('meeting_id = ?'); values.push(updates.meetingId); }\n if (updates.agendaItem !== undefined) { fields.push('agenda_item = ?'); values.push(updates.agendaItem); }\n if (updates.summary !== undefined) { fields.push('summary = ?'); values.push(updates.summary); }\n if (updates.options !== undefined) { fields.push('options = ?'); values.push(JSON.stringify(updates.options)); }\n if (updates.urgency !== undefined) { fields.push('urgency = ?'); values.push(updates.urgency); }\n if (updates.status !== undefined) { fields.push('status = ?'); values.push(updates.status); }\n if (updates.userDecision !== undefined) { fields.push('user_decision = ?'); values.push(updates.userDecision); }\n if (updates.userReasoning !== undefined) { fields.push('user_reasoning = ?'); values.push(updates.userReasoning); }\n if (updates.createdAt !== undefined) { fields.push('created_at = ?'); values.push(updates.createdAt); }\n if (updates.resolvedAt !== undefined) { fields.push('resolved_at = ?'); values.push(updates.resolvedAt); }\n\n if (fields.length === 0) return existing;\n\n values.push(id);\n db.prepare(`UPDATE mentions SET ${fields.join(', ')} WHERE id = ?`).run(...values);\n\n return getMention(id);\n}\n\nexport function listPendingMentions(): MentionRecord[] {\n const db = getDb();\n const rows = db\n .prepare(\"SELECT * FROM mentions WHERE status = 'pending' ORDER BY created_at ASC\")\n .all() as MentionRow[];\n return rows.map(rowToMention);\n}\n\nexport function listMentionsByMeeting(meetingId: string): MentionRecord[] {\n const db = getDb();\n const rows = db\n .prepare('SELECT * FROM mentions WHERE meeting_id = ? ORDER BY created_at ASC')\n .all(meetingId) as MentionRow[];\n return rows.map(rowToMention);\n}\n","import { v4 as uuidv4 } from 'uuid';\nimport { getDb } from './db.js';\nimport type { MinutesRecord, MinutesFormat, ActionItem } from '../types/index.js';\n\ninterface MinutesRow {\n id: string;\n meeting_id: string;\n format: string;\n content: string;\n action_items: string;\n created_at: number;\n}\n\nfunction rowToMinutes(row: MinutesRow): MinutesRecord {\n return {\n id: row.id,\n meetingId: row.meeting_id,\n format: row.format as MinutesFormat,\n content: row.content,\n actionItems: JSON.parse(row.action_items) as ActionItem[],\n createdAt: row.created_at,\n };\n}\n\nexport function createMinutes(\n minutes: Omit<MinutesRecord, 'id' | 'createdAt'> & {\n id?: string;\n createdAt?: number;\n }\n): MinutesRecord {\n const db = getDb();\n const id = minutes.id ?? uuidv4();\n const createdAt = minutes.createdAt ?? Date.now();\n\n db.prepare(\n `INSERT INTO minutes (id, meeting_id, format, content, action_items, created_at)\n VALUES (?, ?, ?, ?, ?, ?)`\n ).run(\n id,\n minutes.meetingId,\n minutes.format,\n minutes.content,\n JSON.stringify(minutes.actionItems),\n createdAt\n );\n\n return {\n id,\n meetingId: minutes.meetingId,\n format: minutes.format,\n content: minutes.content,\n actionItems: minutes.actionItems,\n createdAt,\n };\n}\n\nexport function getMinutesByMeeting(meetingId: string): MinutesRecord | null {\n const db = getDb();\n const row = db\n .prepare('SELECT * FROM minutes WHERE meeting_id = ?')\n .get(meetingId) as MinutesRow | undefined;\n return row ? rowToMinutes(row) : null;\n}\n","import { getDb } from './db.js';\nimport type { ActionItem } from '../types/index.js';\n\ninterface MinutesRow {\n id: string;\n meeting_id: string;\n action_items: string;\n}\n\nexport function getTasksFromMinutes(meetingId: string): ActionItem[] {\n const db = getDb();\n const row = db\n .prepare('SELECT action_items FROM minutes WHERE meeting_id = ?')\n .get(meetingId) as Pick<MinutesRow, 'action_items'> | undefined;\n\n if (!row) return [];\n\n return JSON.parse(row.action_items) as ActionItem[];\n}\n\nexport function updateTaskInMinutes(\n meetingId: string,\n taskId: string,\n updates: Partial<Omit<ActionItem, 'id'>>\n): ActionItem | null {\n const db = getDb();\n const row = db\n .prepare('SELECT id, action_items FROM minutes WHERE meeting_id = ?')\n .get(meetingId) as Pick<MinutesRow, 'id' | 'action_items'> | undefined;\n\n if (!row) return null;\n\n const actionItems = JSON.parse(row.action_items) as ActionItem[];\n const index = actionItems.findIndex((item) => item.id === taskId);\n\n if (index === -1) return null;\n\n const updated: ActionItem = { ...actionItems[index], ...updates, id: taskId };\n actionItems[index] = updated;\n\n db.prepare('UPDATE minutes SET action_items = ? WHERE id = ?').run(\n JSON.stringify(actionItems),\n row.id\n );\n\n return updated;\n}\n","export type AgentTier = 'orchestrator' | 'leader' | 'worker';\n\nexport type AgentStatus =\n | 'idle'\n | 'in-meeting'\n | 'working'\n | 'spawning-workers'\n | 'aggregating'\n | 'waiting-for-user'\n | 'completed'\n | 'failed';\n\nexport type Department =\n | 'architecture'\n | 'engineering'\n | 'qa'\n | 'product'\n | 'research';\n\nexport type LeaderRole =\n | 'arch-leader'\n | 'eng-leader'\n | 'qa-leader'\n | 'pm-leader'\n | 'research-leader';\n\nexport type WorkerType =\n | 'schema-designer'\n | 'api-designer'\n | 'dependency-analyzer'\n | 'feature-dev'\n | 'bug-fixer'\n | 'refactorer'\n | 'test-writer'\n | 'test-runner'\n | 'security-auditor'\n | 'perf-tester'\n | 'requirements-analyzer'\n | 'user-flow-mapper'\n | 'code-explorer'\n | 'doc-searcher'\n | 'benchmark-runner'\n | 'minutes-writer'\n | 'compactor';\n\nexport interface AgentNode {\n id: string;\n tier: AgentTier;\n role: string;\n department: Department;\n parentId: string | null;\n meetingId: string | null;\n status: AgentStatus;\n currentTask: string | null;\n sessionId: string | null;\n spawnedAt: number;\n completedAt: number | null;\n costUsd: number;\n}\n\nexport interface AgentConfig {\n model: string;\n maxTurns: number;\n\n allowedTools: string[];\n}\n\nexport const TIER_CONFIGS: Record<AgentTier, Omit<AgentConfig, 'allowedTools'>> = {\n orchestrator: {\n model: 'claude-opus-4-6',\n maxTurns: 10,\n },\n leader: {\n model: 'claude-sonnet-4-6',\n maxTurns: 20,\n },\n worker: {\n model: 'claude-sonnet-4-6',\n maxTurns: 30,\n },\n};\n\nexport const DEPARTMENT_TOOLS: Record<Department, string[]> = {\n architecture: ['Read', 'Grep', 'Glob'],\n engineering: ['Read', 'Grep', 'Glob', 'Write', 'Edit', 'Bash'],\n qa: ['Read', 'Grep', 'Glob', 'Bash'],\n product: ['Read'],\n research: ['Read', 'Grep', 'Glob', 'WebSearch'],\n};\n","export type MeetingStatus =\n | 'pending'\n | 'convening'\n | 'opening'\n | 'discussion'\n | 'synthesis'\n | 'minutes-generation'\n | 'completed'\n | 'compacted'\n | 'executing'\n | 'aggregation'\n | 'reported'\n | 'waiting-for-user'\n | 'cancelled'\n | 'failed';\n\nexport type MeetingPhase =\n | 'orchestrator-phase'\n | 'convening'\n | 'opening'\n | 'discussion'\n | 'research-break'\n | 'synthesis'\n | 'minutes-generation';\n\nexport interface Meeting {\n id: string;\n topic: string;\n agenda: string[];\n participantIds: string[];\n status: MeetingStatus;\n phase: MeetingPhase;\n startedAt: number | null;\n completedAt: number | null;\n initiatedBy: string;\n previousMeetingId: string | null;\n}\n\nexport interface MeetingConfig {\n maxRoundsPerItem: number;\n convergenceThreshold: number;\n model: string;\n}\n\nexport const DEFAULT_MEETING_CONFIG: MeetingConfig = {\n maxRoundsPerItem: 3,\n convergenceThreshold: 0.8,\n model: 'claude-sonnet-4-6',\n};\n\nexport interface TranscriptEntry {\n id: number;\n meetingId: string;\n speakerId: string;\n speakerRole: string;\n agendaItemIndex: number;\n roundNumber: number;\n content: string;\n tokenCount: number;\n createdAt: number;\n}\n","import type { Department, LeaderRole, WorkerType } from '../types/index.js';\nimport { DEPARTMENT_TOOLS } from '../types/index.js';\n\n/** Full metadata for a department. */\nexport interface DepartmentInfo {\n name: Department;\n description: string;\n leaderRole: LeaderRole;\n workerTypes: WorkerType[];\n allowedTools: string[];\n}\n\nconst DEPARTMENT_REGISTRY: ReadonlyMap<Department, DepartmentInfo> = new Map<Department, DepartmentInfo>([\n [\n 'architecture',\n {\n name: 'architecture',\n description:\n 'Responsible for system design, schema definitions, API surface design, and dependency analysis. ' +\n 'The architecture department plans before code is written — it produces blueprints, not implementations.',\n leaderRole: 'arch-leader',\n workerTypes: ['schema-designer', 'api-designer', 'dependency-analyzer'],\n allowedTools: DEPARTMENT_TOOLS.architecture,\n },\n ],\n [\n 'engineering',\n {\n name: 'engineering',\n description:\n 'Responsible for writing, modifying, and refactoring production code. ' +\n 'Engineering owns feature development, bug fixes, and code quality improvements.',\n leaderRole: 'eng-leader',\n workerTypes: ['feature-dev', 'bug-fixer', 'refactorer'],\n allowedTools: DEPARTMENT_TOOLS.engineering,\n },\n ],\n [\n 'qa',\n {\n name: 'qa',\n description:\n 'Responsible for test creation, test execution, security auditing, and performance testing. ' +\n 'QA ensures deliverables meet acceptance criteria and do not introduce regressions.',\n leaderRole: 'qa-leader',\n workerTypes: ['test-writer', 'test-runner', 'security-auditor', 'perf-tester'],\n allowedTools: DEPARTMENT_TOOLS.qa,\n },\n ],\n [\n 'product',\n {\n name: 'product',\n description:\n 'Responsible for requirements analysis, user-flow mapping, and stakeholder alignment. ' +\n 'Product translates user intent into well-scoped, actionable requirements for other departments.',\n leaderRole: 'pm-leader',\n workerTypes: ['requirements-analyzer', 'user-flow-mapper'],\n allowedTools: DEPARTMENT_TOOLS.product,\n },\n ],\n [\n 'research',\n {\n name: 'research',\n description:\n 'Responsible for codebase exploration, documentation search, benchmarking, and knowledge gathering. ' +\n 'Research produces facts and context that inform decisions made by other departments.',\n leaderRole: 'research-leader',\n workerTypes: ['code-explorer', 'doc-searcher', 'benchmark-runner'],\n allowedTools: DEPARTMENT_TOOLS.research,\n },\n ],\n]);\n\n/** Reverse lookup: leader role → department. */\nconst ROLE_TO_DEPARTMENT: ReadonlyMap<LeaderRole, Department> = new Map<LeaderRole, Department>(\n [...DEPARTMENT_REGISTRY.values()].map((d) => [d.leaderRole, d.name]),\n);\n\n/**\n * Get the full metadata for a single department.\n * Throws if the department key is unknown.\n */\nexport function getDepartment(dept: Department): DepartmentInfo {\n const info = DEPARTMENT_REGISTRY.get(dept);\n if (!info) {\n throw new Error(`Unknown department: ${dept}`);\n }\n return info;\n}\n\n/**\n * Return metadata for every registered department.\n */\nexport function getAllDepartments(): DepartmentInfo[] {\n return [...DEPARTMENT_REGISTRY.values()];\n}\n\n/**\n * Resolve a leader role back to its owning department.\n * Throws if the role is unknown.\n */\nexport function getDepartmentForRole(role: LeaderRole): Department {\n const dept = ROLE_TO_DEPARTMENT.get(role);\n if (dept === undefined) {\n throw new Error(`Unknown leader role: ${role}`);\n }\n return dept;\n}\n","import { EventEmitter } from 'node:events';\nimport type { AgentEvent, DashboardEvent } from '../types/index.js';\n\n// ---------------------------------------------------------------------------\n// Typed event map\n// ---------------------------------------------------------------------------\n\n/**\n * Events emitted by the internal event bus.\n *\n * - `agent_event` — individual agent lifecycle events (spawned, destroyed, state change, etc.)\n * - `dashboard` — full dashboard payloads (snapshot or delta) intended for the WebSocket dashboard.\n */\nexport interface EventBusEvents {\n agent_event: [event: AgentEvent];\n dashboard: [event: DashboardEvent];\n}\n\n// ---------------------------------------------------------------------------\n// EventBus class\n// ---------------------------------------------------------------------------\n\nclass EventBus {\n private readonly emitter = new EventEmitter();\n\n constructor() {\n // Allow a reasonable number of listeners (leaders + dashboard + internal consumers)\n this.emitter.setMaxListeners(50);\n }\n\n // ---- emit ---------------------------------------------------------------\n\n /**\n * Emit a single agent lifecycle event.\n *\n * The event is:\n * 1. Broadcast to all `agent_event` listeners.\n * 2. Wrapped in a `delta` dashboard event and broadcast to `dashboard` listeners.\n * 3. (Planned) Persisted to SQLite via the storage layer.\n */\n emitAgentEvent(event: AgentEvent): void {\n this.emitter.emit('agent_event', event);\n\n // Wrap in a delta for the dashboard\n const delta: DashboardEvent = {\n type: 'delta',\n timestamp: Date.now(),\n events: [event],\n };\n this.emitter.emit('dashboard', delta);\n\n // TODO: persist to SQLite once the storage layer is implemented\n // import { eventStore } from '../storage/event-store.js';\n // eventStore.persist(event);\n }\n\n /**\n * Emit a full dashboard snapshot (used on initial WebSocket connection).\n */\n emitDashboardSnapshot(snapshot: DashboardEvent): void {\n this.emitter.emit('dashboard', snapshot);\n }\n\n // ---- subscribe ----------------------------------------------------------\n\n on<K extends keyof EventBusEvents>(event: K, listener: (...args: EventBusEvents[K]) => void): void {\n this.emitter.on(event, listener as (...args: unknown[]) => void);\n }\n\n off<K extends keyof EventBusEvents>(event: K, listener: (...args: EventBusEvents[K]) => void): void {\n this.emitter.off(event, listener as (...args: unknown[]) => void);\n }\n\n once<K extends keyof EventBusEvents>(event: K, listener: (...args: EventBusEvents[K]) => void): void {\n this.emitter.once(event, listener as (...args: unknown[]) => void);\n }\n\n // ---- utility ------------------------------------------------------------\n\n removeAllListeners(event?: keyof EventBusEvents): void {\n if (event) {\n this.emitter.removeAllListeners(event);\n } else {\n this.emitter.removeAllListeners();\n }\n }\n\n listenerCount(event: keyof EventBusEvents): number {\n return this.emitter.listenerCount(event);\n }\n}\n\n// ---------------------------------------------------------------------------\n// Singleton export\n// ---------------------------------------------------------------------------\n\n/** Global event bus singleton for internal inter-agent communication. */\nexport const eventBus = new EventBus();\n","/**\n * Structured logger that writes to stderr.\n *\n * stdout is reserved for the MCP stdio transport, so all diagnostic output\n * goes to stderr to avoid corrupting the JSON-RPC stream.\n */\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport type LogLevel = 'debug' | 'info' | 'warn' | 'error';\n\nexport interface LogContext {\n meetingId?: string;\n agentId?: string;\n department?: string;\n [key: string]: unknown;\n}\n\ninterface LogEntry {\n timestamp: string;\n level: LogLevel;\n message: string;\n context?: LogContext;\n}\n\n// ---------------------------------------------------------------------------\n// Level ordering\n// ---------------------------------------------------------------------------\n\nconst LEVEL_PRIORITY: Record<LogLevel, number> = {\n debug: 0,\n info: 1,\n warn: 2,\n error: 3,\n};\n\n// ---------------------------------------------------------------------------\n// Logger class\n// ---------------------------------------------------------------------------\n\nclass Logger {\n private minLevel: LogLevel = 'info';\n\n /**\n * Set the minimum log level. Messages below this level are silently dropped.\n * Defaults to 'info'. Set to 'debug' for verbose output.\n */\n setLevel(level: LogLevel): void {\n this.minLevel = level;\n }\n\n getLevel(): LogLevel {\n return this.minLevel;\n }\n\n debug(message: string, context?: LogContext): void {\n this.log('debug', message, context);\n }\n\n info(message: string, context?: LogContext): void {\n this.log('info', message, context);\n }\n\n warn(message: string, context?: LogContext): void {\n this.log('warn', message, context);\n }\n\n error(message: string, context?: LogContext): void {\n this.log('error', message, context);\n }\n\n // -----------------------------------------------------------------------\n // Internal\n // -----------------------------------------------------------------------\n\n private log(level: LogLevel, message: string, context?: LogContext): void {\n if (LEVEL_PRIORITY[level] < LEVEL_PRIORITY[this.minLevel]) {\n return;\n }\n\n const entry: LogEntry = {\n timestamp: new Date().toISOString(),\n level,\n message,\n };\n\n if (context && Object.keys(context).length > 0) {\n entry.context = context;\n }\n\n // Write to stderr as a single JSON line for easy parsing\n process.stderr.write(JSON.stringify(entry) + '\\n');\n }\n}\n\n// ---------------------------------------------------------------------------\n// Singleton export\n// ---------------------------------------------------------------------------\n\n/** Global structured logger — writes to stderr to keep stdout clean for MCP. */\nexport const logger = new Logger();\n","import { v4 as uuidv4 } from 'uuid';\nimport type { AgentNode, Department } from '../types/index.js';\nimport { createAgent, updateAgent, listAgentsByMeeting } from '../storage/index.js';\nimport { getDepartment } from '../agents/departments.js';\nimport { eventBus } from './event-bus.js';\nimport { logger } from '../utils/logger.js';\n\n// ---------------------------------------------------------------------------\n// LeaderPool — manages leader agent lifecycles\n// ---------------------------------------------------------------------------\n\nexport class LeaderPool {\n /**\n * Active leaders keyed by their agent ID.\n * This is a fast in-memory index; the source of truth is SQLite.\n */\n private readonly activeLeaders = new Map<string, AgentNode>();\n\n // ---- spawn --------------------------------------------------------------\n\n /**\n * Spawn a new leader agent for the given department and meeting.\n *\n * Persists the agent to SQLite and emits an `agent_spawned` event on the\n * event bus.\n */\n spawnLeader(department: Department, meetingId: string): AgentNode {\n const deptInfo = getDepartment(department);\n\n const agent = createAgent({\n tier: 'leader',\n role: deptInfo.leaderRole,\n department,\n parentId: null, // The orchestrator is implicit; no stored orchestrator agent row yet.\n meetingId,\n status: 'in-meeting',\n currentTask: null,\n sessionId: null,\n });\n\n this.activeLeaders.set(agent.id, agent);\n\n logger.info(`Spawned leader: ${deptInfo.leaderRole}`, {\n agentId: agent.id,\n department,\n meetingId,\n });\n\n eventBus.emitAgentEvent({\n kind: 'agent_spawned',\n agentId: agent.id,\n agentType: 'leader',\n parentId: null,\n label: deptInfo.leaderRole,\n department,\n });\n\n return agent;\n }\n\n // ---- query --------------------------------------------------------------\n\n /**\n * Return all currently-active leaders assigned to a given meeting.\n *\n * Falls back to a SQLite query filtered by status so that leaders which were\n * deactivated out-of-band are excluded.\n */\n getLeadersForMeeting(meetingId: string): AgentNode[] {\n // Fast path: filter in-memory cache\n const fromCache = [...this.activeLeaders.values()].filter(\n (a) => a.meetingId === meetingId,\n );\n\n if (fromCache.length > 0) {\n return fromCache;\n }\n\n // Slow path: query storage (e.g. after a server restart)\n return listAgentsByMeeting(meetingId).filter(\n (a) => a.tier === 'leader' && a.status !== 'completed' && a.status !== 'failed',\n );\n }\n\n // ---- deactivate ---------------------------------------------------------\n\n /**\n * Mark a leader as completed and remove it from the in-memory cache.\n */\n deactivateLeader(leaderId: string): void {\n const leader = this.activeLeaders.get(leaderId);\n\n updateAgent(leaderId, {\n status: 'completed',\n completedAt: Date.now(),\n });\n\n this.activeLeaders.delete(leaderId);\n\n logger.info(`Deactivated leader: ${leaderId}`, {\n agentId: leaderId,\n department: leader?.department,\n });\n\n eventBus.emitAgentEvent({\n kind: 'agent_destroyed',\n agentId: leaderId,\n });\n }\n}\n","import type { Department } from '../types/index.js';\nimport { getDepartment } from './departments.js';\n\n// ---------------------------------------------------------------------------\n// Internal helpers\n// ---------------------------------------------------------------------------\n\nfunction rulesBlock(extraRules?: string[]): string {\n const base = [\n 'Never modify files outside the project root unless explicitly told to.',\n 'Never commit, push, or deploy without a confirmed user decision.',\n 'If you encounter ambiguity that could lead to significant rework, emit @USER_DECISION_NEEDED immediately rather than guessing.',\n 'Keep responses concise. Prefer structured output (lists, tables) over prose.',\n 'When delegating to workers, provide clear task descriptions with explicit acceptance criteria.',\n 'Respect the tool allowlist for your department — do not attempt to use tools you have not been granted.',\n 'Report cost and token usage whenever you complete a significant sub-task.',\n ];\n const rules = extraRules ? [...base, ...extraRules] : base;\n return rules.map((r, i) => `${i + 1}. ${r}`).join('\\n');\n}\n\nfunction meetingProtocol(): string {\n return `## MEETING PROTOCOL\n\nWhen participating in a meeting you MUST follow these rules:\n\n1. **Opening phase** — Listen to the agenda presented by the orchestrator. Acknowledge understanding. Surface any concerns or dependencies your department has regarding the agenda items.\n\n2. **Discussion phase** — Contribute your department's perspective on each agenda item. Be specific: reference files, modules, or prior decisions. If you disagree with another leader, state your reasoning clearly and propose an alternative.\n\n3. **When to emit @USER_DECISION_NEEDED** — Emit this tag ONLY when:\n - Two or more leaders have irreconcilable positions after a full discussion round.\n - A decision has significant cost, security, or architectural implications that exceed the meeting's delegated authority.\n - The user explicitly asked to be looped in on a particular topic.\n Include: a concise summary of the options, who supports each option, and your recommended default.\n\n4. **Synthesis phase** — Confirm or amend the proposed action items. Ensure your department's commitments are accurate and achievable.\n\n5. **Post-meeting** — Execute your assigned action items by spawning workers or performing lightweight tasks directly.`;\n}\n\nfunction workforceManagement(deptDescription: string, workerTypes: string[]): string {\n return `## WORKFORCE MANAGEMENT\n\nYou lead the department: ${deptDescription}\n\nAvailable worker types you can spawn: ${workerTypes.join(', ')}\n\n### When to spawn workers\n- Spawn workers for tasks that require focused execution (file changes, test runs, research).\n- Do NOT spawn workers for simple questions you can answer from context.\n- Prefer spawning multiple independent workers in parallel over sequential single-worker chains.\n\n### How to spawn workers\nWhen you decide a worker is needed, output a structured worker-spawn request:\n\\`\\`\\`\nSPAWN_WORKER:\n type: <worker-type>\n task: <one-line description>\n context: <relevant files, decisions, or constraints>\n acceptance_criteria:\n - <criterion 1>\n - <criterion 2>\n\\`\\`\\`\n\n### Aggregating results\nWhen workers complete, review their output:\n- If a worker succeeded — incorporate the result and move forward.\n- If a worker failed — diagnose the failure. Retry with adjusted instructions or escalate in the meeting.\n- Summarise aggregated results before reporting back to the meeting.`;\n}\n\n// ---------------------------------------------------------------------------\n// Per-role identity blocks\n// ---------------------------------------------------------------------------\n\nconst IDENTITIES: Record<string, string> = {\n 'arch-leader': `## IDENTITY\n\nYou are the **Architecture Leader**. You own system design decisions for this project.\n\nYour responsibilities:\n- Evaluate and propose system architecture (module boundaries, data flow, APIs).\n- Design database schemas and data models.\n- Analyse dependency graphs and flag coupling or circular-dependency risks.\n- Ensure new features fit the existing architecture; propose refactors when they do not.\n- Produce architecture decision records (ADRs) when significant choices are made.\n\nYou are a planner, not an implementer. You produce blueprints and hand implementation to Engineering.`,\n\n 'eng-leader': `## IDENTITY\n\nYou are the **Engineering Leader**. You own code quality and delivery for this project.\n\nYour responsibilities:\n- Break down approved designs into implementable tasks.\n- Assign coding work to feature-dev, bug-fixer, and refactorer workers.\n- Review worker output for correctness, style, and adherence to project conventions.\n- Coordinate with QA to ensure changes are testable.\n- Flag technical debt and propose refactoring when it reaches a threshold.\n\nYou write and ship code through your workers. You translate architecture into working software.`,\n\n 'qa-leader': `## IDENTITY\n\nYou are the **QA Leader**. You own quality assurance, testing strategy, and security posture.\n\nYour responsibilities:\n- Define test plans: unit tests, integration tests, and end-to-end flows.\n- Spawn test-writer workers to create tests for new or changed code.\n- Spawn test-runner workers to execute test suites and report results.\n- Spawn security-auditor workers when new dependencies or sensitive code paths are introduced.\n- Spawn perf-tester workers for performance-critical changes.\n- Block merges that lack adequate test coverage or have failing tests.\n\nYou are the project's quality gate. Nothing ships without your sign-off.`,\n\n 'pm-leader': `## IDENTITY\n\nYou are the **Product Leader**. You own requirements clarity and user-facing coherence.\n\nYour responsibilities:\n- Analyse user requests and translate them into structured requirements.\n- Map user flows to ensure feature completeness and good UX.\n- Prioritise work items when resources are limited.\n- Ensure the team is building what the user actually asked for, not what was assumed.\n- Write acceptance criteria that other departments can verify against.\n\nYou are the voice of the user inside the team. You bridge intent and implementation.`,\n\n 'research-leader': `## IDENTITY\n\nYou are the **Research Leader**. You own information gathering and knowledge synthesis.\n\nYour responsibilities:\n- Explore the existing codebase to answer questions from other departments.\n- Search documentation, READMEs, and external resources for relevant context.\n- Run benchmarks when quantitative data is needed for a decision.\n- Summarise findings in a structured, citable format.\n- Maintain a knowledge base of discovered facts about the project.\n\nYou provide the evidence base. Other departments make decisions; you supply the facts.`,\n};\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Build a full system prompt for a department leader.\n *\n * @param department The department this leader represents.\n * @param rules Optional extra rules to append to the default rule set.\n * @returns A complete system prompt string.\n */\nexport function getLeaderSystemPrompt(\n department: Department,\n rules?: string[],\n projectContext?: string,\n): string {\n const dept = getDepartment(department);\n const identity = IDENTITIES[dept.leaderRole];\n if (!identity) {\n throw new Error(`No identity prompt defined for leader role: ${dept.leaderRole}`);\n }\n\n const sections = [\n identity,\n meetingProtocol(),\n workforceManagement(dept.description, dept.workerTypes),\n `## RULES\\n\\n${rulesBlock(rules)}`,\n ];\n\n if (projectContext) {\n sections.push(projectContext);\n }\n\n return sections.join('\\n\\n');\n}\n","import type { AgentTier, AgentConfig } from '../types/index.js';\nimport { TIER_CONFIGS } from '../types/index.js';\n\n/**\n * Valid parent→child relationships in the agent hierarchy.\n *\n * orchestrator → leader → worker\n *\n * An orchestrator can spawn leaders. A leader can spawn workers.\n * No other parent→child combination is allowed.\n */\nconst VALID_HIERARCHY: ReadonlyMap<AgentTier, AgentTier> = new Map([\n ['orchestrator', 'leader'],\n ['leader', 'worker'],\n]);\n\n/**\n * Returns `true` when `parentTier` is allowed to spawn a child of `childTier`.\n *\n * Rules:\n * - orchestrator → leader ✔\n * - leader → worker ✔\n * - everything else ✘\n */\nexport function isValidParent(parentTier: AgentTier, childTier: AgentTier): boolean {\n return VALID_HIERARCHY.get(parentTier) === childTier;\n}\n\n/**\n * Look up the tier-level configuration (model, maxTurns).\n *\n * Returns a copy so callers can safely mutate the result without affecting\n * the shared config.\n */\nexport function getTierConfig(tier: AgentTier): Omit<AgentConfig, 'allowedTools'> {\n const config = TIER_CONFIGS[tier];\n if (!config) {\n throw new Error(`Unknown agent tier: ${tier}`);\n }\n return { ...config };\n}\n","import type { Department, WorkerType } from '../types/index.js';\n\n/** Options for building a worker system prompt. */\nexport interface WorkerPromptOptions {\n workerType: WorkerType;\n department: Department;\n task: string;\n context?: string;\n projectContext?: string;\n}\n\n// ---------------------------------------------------------------------------\n// Worker-type descriptions\n// ---------------------------------------------------------------------------\n\nconst WORKER_DESCRIPTIONS: Record<WorkerType, string> = {\n // Architecture workers\n 'schema-designer':\n 'You design database schemas and data models. Output CREATE TABLE statements, type definitions, or ERD descriptions.',\n 'api-designer':\n 'You design API surfaces — REST endpoints, RPC methods, or function signatures. Output OpenAPI snippets or typed interface definitions.',\n 'dependency-analyzer':\n 'You analyse project dependencies and module coupling. Output dependency graphs, circular-dependency reports, or upgrade recommendations.',\n\n // Engineering workers\n 'feature-dev':\n 'You implement new features by writing production code. Follow the project conventions. Output complete, working code changes.',\n 'bug-fixer':\n 'You diagnose and fix bugs. Read the relevant code, identify the root cause, and produce a minimal correct fix.',\n 'refactorer':\n 'You improve existing code without changing its behaviour. Focus on readability, performance, or reducing duplication.',\n\n // QA workers\n 'test-writer':\n 'You write test cases — unit, integration, or end-to-end. Ensure each test has a clear assertion and covers the acceptance criteria.',\n 'test-runner':\n 'You execute test suites and report results. Run commands, capture output, and summarise pass/fail counts and failures.',\n 'security-auditor':\n 'You audit code for security vulnerabilities — injection, auth issues, insecure dependencies, exposed secrets. Output a structured finding list.',\n 'perf-tester':\n 'You run performance tests and benchmarks. Measure response time, throughput, or resource usage and report quantitative results.',\n\n // Product workers\n 'requirements-analyzer':\n 'You analyse user requests and existing documentation to produce structured requirements with acceptance criteria.',\n 'user-flow-mapper':\n 'You trace user-facing flows through the system — from input to output — and document each step, decision point, and edge case.',\n\n // Research workers\n 'code-explorer':\n 'You explore the codebase to answer specific questions. Read files, trace call chains, and summarise your findings.',\n 'doc-searcher':\n 'You search documentation, READMEs, comments, and external references to find relevant information.',\n 'benchmark-runner':\n 'You run benchmarks and collect quantitative data. Output structured results with methodology notes.',\n\n // Cross-cutting workers\n 'minutes-writer':\n 'You write structured meeting minutes from a transcript. Output: summary, decisions, action items, and @mentions.',\n compactor:\n 'You compact long conversation transcripts into a shorter summary that preserves all decisions, action items, and open questions.',\n};\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Build a focused single-task system prompt for a worker agent.\n *\n * The prompt includes:\n * 1. Worker identity and capability description\n * 2. The specific task to perform\n * 3. Optional context (files, prior decisions, constraints)\n * 4. Output expectations and rules\n */\nexport function buildWorkerPrompt(opts: WorkerPromptOptions): string {\n const { workerType, department, task, context, projectContext } = opts;\n\n const description = WORKER_DESCRIPTIONS[workerType];\n if (!description) {\n throw new Error(`Unknown worker type: ${workerType}`);\n }\n\n const sections: string[] = [\n `## IDENTITY\n\nYou are a **${workerType}** worker in the **${department}** department.\n\n${description}`,\n\n `## TASK\n\n${task}`,\n ];\n\n if (context) {\n sections.push(`## CONTEXT\n\n${context}`);\n }\n\n if (projectContext) {\n sections.push(projectContext);\n }\n\n sections.push(`## OUTPUT RULES\n\n1. Stay focused on the single task above. Do not wander into unrelated work.\n2. If the task is impossible or blocked, explain why clearly and stop — do not produce partial or guessed output.\n3. Prefer structured output: code blocks, lists, tables.\n4. Include file paths (always absolute) when referencing code.\n5. When your task is complete, end with a brief summary of what you did and any caveats.\n6. Respect the tool allowlist for the ${department} department — do not attempt to use tools you have not been granted.\n7. Do not commit, push, or deploy. Your output will be reviewed by your leader before any permanent action is taken.`);\n\n return sections.join('\\n\\n');\n}\n","import type { AgentTier, Department, WorkerType, AgentConfig } from '../types/index.js';\nimport { DEPARTMENT_TOOLS } from '../types/index.js';\nimport { getTierConfig } from './tiers.js';\nimport { getLeaderSystemPrompt } from './leader-prompts.js';\nimport { buildWorkerPrompt } from './worker-prompts.js';\nimport { getDepartment } from './departments.js';\n\n// ---------------------------------------------------------------------------\n// Orchestrator system prompt\n// ---------------------------------------------------------------------------\n\nconst ORCHESTRATOR_SYSTEM_PROMPT = `## IDENTITY\n\nYou are the **Orchestrator** — a proxy and router, NOT a CEO. Your job is to receive the user's request, decompose it into department-level concerns, convene meetings, and route work to the appropriate leaders. You do not make product, architecture, or engineering decisions yourself.\n\n## CORE RESPONSIBILITIES\n\n1. **Request analysis** — When the user submits a request, determine which departments are relevant. Most requests involve 2-4 departments.\n\n2. **Meeting convening** — Create a meeting with an agenda derived from the request. Invite the relevant leaders. You chair the meeting but you do not dominate it.\n\n3. **Auto-routing** — For straightforward, single-department tasks (e.g., \"run the tests\"), skip the full meeting flow and route directly to the responsible leader.\n\n4. **@USER mentions** — When a leader emits @USER_DECISION_NEEDED during a meeting:\n - Pause the meeting.\n - Surface the decision to the user with full context (options, trade-offs, supporters).\n - Resume the meeting once the user responds.\n\n5. **Progress tracking** — Monitor worker completion events. Nudge leaders if a task is overdue or failed. Report final results back to the user.\n\n## RULES\n\n1. You are a facilitator. Do NOT override leader recommendations unless they conflict with an explicit user instruction.\n2. Keep your own token usage minimal — delegate analysis and execution to leaders and workers.\n3. Always preserve the user's exact wording when forwarding a request to a meeting.\n4. If the user's request is ambiguous, ask a clarifying question BEFORE convening a meeting.\n5. Never modify files, run tests, or execute code directly. All execution happens through workers spawned by leaders.\n6. When multiple departments disagree, facilitate resolution. Escalate to the user only when the team cannot converge after a full discussion round.\n7. After a meeting completes, provide the user with a concise summary: decisions made, action items, and any pending @USER items.\n8. Respect budget limits. If projected cost approaches the meeting budget, warn the user and request approval before proceeding.\n\n## DEPARTMENT OVERVIEW\n\nYou can route work to these departments:\n- **architecture** — System design, schemas, API surfaces, dependency analysis.\n- **engineering** — Feature implementation, bug fixes, refactoring.\n- **qa** — Testing, security audits, performance testing.\n- **product** — Requirements analysis, user-flow mapping, prioritisation.\n- **research** — Codebase exploration, documentation search, benchmarks.\n\n## OUTPUT FORMAT\n\nWhen you need to convene a meeting, output:\n\\`\\`\\`\nCONVENE_MEETING:\n topic: <meeting topic>\n agenda:\n - <item 1>\n - <item 2>\n departments:\n - <dept 1>\n - <dept 2>\n\\`\\`\\`\n\nWhen you route directly to a leader (no meeting), output:\n\\`\\`\\`\nDIRECT_ROUTE:\n department: <department>\n task: <task description>\n\\`\\`\\`\n`;\n\n// ---------------------------------------------------------------------------\n// Options\n// ---------------------------------------------------------------------------\n\nexport interface CreateAgentConfigOptions {\n tier: AgentTier;\n role: string;\n department: Department;\n task?: string;\n context?: string;\n}\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Build a complete agent configuration suitable for the Claude Agent SDK.\n *\n * - For **orchestrator**: uses the built-in orchestrator system prompt.\n * - For **leaders**: uses the department-specific leader prompt.\n * - For **workers**: uses the focused worker prompt builder.\n * - Research workers override the model to `claude-haiku-4-5` and cap budget at $0.10.\n */\nexport function createAgentConfig(opts: CreateAgentConfigOptions): AgentConfig {\n const { tier, role, department, task, context } = opts;\n\n // Base config from tier\n const tierCfg = getTierConfig(tier);\n\n // Determine allowed tools\n const allowedTools: string[] = [...(DEPARTMENT_TOOLS[department] ?? [])];\n\n // Build system prompt based on tier\n let systemPrompt: string;\n\n switch (tier) {\n case 'orchestrator': {\n systemPrompt = ORCHESTRATOR_SYSTEM_PROMPT;\n break;\n }\n\n case 'leader': {\n systemPrompt = getLeaderSystemPrompt(department);\n break;\n }\n\n case 'worker': {\n if (!task) {\n throw new Error('Worker agents require a task description');\n }\n systemPrompt = buildWorkerPrompt({\n workerType: role as WorkerType,\n department,\n task,\n context,\n });\n break;\n }\n\n default: {\n const _exhaustive: never = tier;\n throw new Error(`Unknown tier: ${_exhaustive}`);\n }\n }\n\n // Research workers use a lighter model\n const model = (tier === 'worker' && department === 'research')\n ? 'claude-haiku-4-5'\n : tierCfg.model;\n\n return {\n model,\n maxTurns: tierCfg.maxTurns,\n allowedTools,\n };\n}\n\n/**\n * Retrieve the orchestrator system prompt directly (useful for testing or\n * inspection without constructing a full config).\n */\nexport function getOrchestratorSystemPrompt(): string {\n return ORCHESTRATOR_SYSTEM_PROMPT;\n}\n","import { spawn } from 'node:child_process';\nimport { execSync } from 'node:child_process';\nimport type { AgentConfig } from '../types/index.js';\nimport { logger } from '../utils/logger.js';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport interface InvokeOptions {\n prompt: string;\n systemPrompt: string;\n allowedTools: string[];\n maxTurns: number;\n cwd?: string;\n /** Timeout in milliseconds. Defaults to 300_000 (5 min). */\n timeoutMs?: number;\n}\n\nexport interface InvokeResult {\n success: boolean;\n output: string;\n error?: string;\n costUsd?: number;\n}\n\n// ---------------------------------------------------------------------------\n// Mock mode detection\n// ---------------------------------------------------------------------------\n\nlet _claudeAvailable: boolean | null = null;\n\n/**\n * Check whether the `claude` CLI binary is available on PATH.\n * Result is cached after the first check.\n */\nfunction isClaudeAvailable(): boolean {\n if (_claudeAvailable !== null) return _claudeAvailable;\n\n try {\n execSync('which claude', { stdio: 'ignore' });\n _claudeAvailable = true;\n } catch {\n _claudeAvailable = false;\n }\n return _claudeAvailable;\n}\n\n/**\n * Returns `true` when mock mode is active.\n *\n * Mock mode is enabled when:\n * - The environment variable `COLESLAW_MOCK=1` is set, OR\n * - The `claude` CLI is not found on PATH.\n */\nexport function isMockMode(): boolean {\n if (process.env['COLESLAW_MOCK'] === '1') return true;\n return !isClaudeAvailable();\n}\n\n// ---------------------------------------------------------------------------\n// Mock implementation\n// ---------------------------------------------------------------------------\n\n/**\n * Returns a mock response that is deterministic based on the prompt content.\n * Used when Claude CLI is unavailable or when COLESLAW_MOCK=1 is set.\n */\nasync function invokeMock(options: InvokeOptions): Promise<InvokeResult> {\n // Tiny delay to simulate async work\n await new Promise((resolve) => setTimeout(resolve, 30 + Math.random() * 70));\n\n const lower = options.prompt.toLowerCase();\n\n let output: string;\n if (lower.includes('opening') || lower.includes('initial position')) {\n output =\n '[Mock] Acknowledged the agenda. From my department perspective, I see several important considerations. ' +\n 'We should ensure proper separation of concerns and define clear boundaries. ' +\n 'Key concern: we must avoid tight coupling between new and existing components.';\n } else if (lower.includes('synthesis') || lower.includes('final position')) {\n output =\n '[Mock] FINAL POSITION: I support the agreed approach. Action items for my department: ' +\n '(1) Deliver the agreed outputs, (2) Coordinate with dependent departments, ' +\n '(3) Report completion status once done.';\n } else if (lower.includes('discussion') || lower.includes('perspective')) {\n output =\n '[Mock] Building on the previous points, I propose we move forward with the discussed approach. ' +\n 'This aligns with existing patterns and allows parallel work across departments. ' +\n 'I can have my team start on the deliverables immediately.';\n } else if (lower.includes('schema') || lower.includes('design')) {\n output =\n '[Mock] Schema analysis complete. Proposed 3 tables with proper foreign-key relationships and indexes. ' +\n 'No circular dependencies detected.';\n } else if (lower.includes('test')) {\n output =\n '[Mock] Test suite generated: 8 unit tests, 2 integration tests. All assertions use strict equality. ' +\n 'Coverage target: 90%.';\n } else if (lower.includes('implement') || lower.includes('build') || lower.includes('feature')) {\n output =\n '[Mock] Implementation complete. Created 2 new files, modified 1 existing file. ' +\n 'All changes follow project conventions.';\n } else if (lower.includes('research') || lower.includes('explore')) {\n output =\n '[Mock] Research complete. Found 5 relevant code references and 2 documentation entries. ' +\n 'Summary provided in structured format.';\n } else if (lower.includes('security') || lower.includes('audit')) {\n output =\n '[Mock] Security audit complete. No critical vulnerabilities found. ' +\n '1 advisory: ensure input validation on user-facing endpoints.';\n } else if (lower.includes('fix') || lower.includes('bug')) {\n output =\n '[Mock] Bug fix applied. Root cause identified and corrected. Fix verified with regression test.';\n } else {\n output = '[Mock] Task completed successfully. Output ready for review.';\n }\n\n return {\n success: true,\n output,\n costUsd: 0,\n };\n}\n\n// ---------------------------------------------------------------------------\n// Real Claude CLI invocation\n// ---------------------------------------------------------------------------\n\n/**\n * Spawn the `claude` CLI as a subprocess and collect its output.\n *\n * The CLI is invoked in non-interactive `--print` mode with JSON output\n * format, a custom system prompt, tool restrictions, and turn limits.\n */\nasync function invokeReal(options: InvokeOptions): Promise<InvokeResult> {\n const {\n prompt,\n systemPrompt,\n allowedTools,\n maxTurns,\n cwd,\n timeoutMs = 300_000,\n } = options;\n\n const args: string[] = [\n '--print',\n '--output-format', 'json',\n '--no-session-persistence',\n '--bare', // CRITICAL: skip hooks, plugins, MCP — prevents infinite recursion\n ];\n\n if (systemPrompt) {\n args.push('--system-prompt', systemPrompt); // --bare requires full system prompt, not append\n }\n\n if (allowedTools.length > 0) {\n args.push('--allowedTools', allowedTools.join(','));\n }\n\n // Prompt via stdin (avoids ARG_MAX issues with long prompts)\n // Do NOT add prompt as positional arg\n\n logger.info('Invoking Claude CLI', {\n promptLength: prompt.length as unknown as string,\n toolCount: allowedTools.length as unknown as string,\n });\n\n return new Promise<InvokeResult>((resolve) => {\n const child = spawn('claude', args, {\n cwd: cwd ?? process.cwd(),\n stdio: ['pipe', 'pipe', 'pipe'],\n env: { ...process.env },\n });\n\n // Send prompt via stdin\n child.stdin.write(prompt);\n child.stdin.end();\n\n const stdoutChunks: Buffer[] = [];\n const stderrChunks: Buffer[] = [];\n\n child.stdout.on('data', (chunk: Buffer) => {\n stdoutChunks.push(chunk);\n });\n\n child.stderr.on('data', (chunk: Buffer) => {\n stderrChunks.push(chunk);\n });\n\n // Timeout guard\n const timer = setTimeout(() => {\n logger.warn('Claude CLI timed out, killing process', { timeoutMs: timeoutMs as unknown as string });\n child.kill('SIGTERM');\n // Give it a moment to clean up, then force-kill\n setTimeout(() => {\n if (!child.killed) child.kill('SIGKILL');\n }, 5_000);\n }, timeoutMs);\n\n child.on('close', (code) => {\n clearTimeout(timer);\n\n const rawStdout = Buffer.concat(stdoutChunks).toString('utf-8');\n const rawStderr = Buffer.concat(stderrChunks).toString('utf-8');\n\n if (code !== 0) {\n logger.error('Claude CLI exited with non-zero code', {\n exitCode: String(code),\n });\n resolve({\n success: false,\n output: '',\n error: rawStderr || `Claude CLI exited with code ${code}`,\n });\n return;\n }\n\n // Try to parse JSON output from the CLI\n const parsed = parseCliOutput(rawStdout);\n\n logger.info('Claude CLI invocation completed', {\n outputLength: String(parsed.output.length),\n });\n\n resolve(parsed);\n });\n\n child.on('error', (err) => {\n clearTimeout(timer);\n logger.error('Failed to spawn Claude CLI', { error: err.message });\n resolve({\n success: false,\n output: '',\n error: `Failed to spawn Claude CLI: ${err.message}`,\n });\n });\n });\n}\n\n// ---------------------------------------------------------------------------\n// Output parsing\n// ---------------------------------------------------------------------------\n\ninterface CliJsonOutput {\n result?: string;\n output?: string;\n cost_usd?: number;\n is_error?: boolean;\n error?: string;\n}\n\n/**\n * Parse the JSON (or plain-text) output from the Claude CLI.\n *\n * The `--output-format json` flag produces a JSON object. If parsing fails\n * we fall back to treating the raw text as the output.\n */\nfunction parseCliOutput(raw: string): InvokeResult {\n const trimmed = raw.trim();\n if (!trimmed) {\n return { success: false, output: '', error: 'Empty output from Claude CLI' };\n }\n\n try {\n const json = JSON.parse(trimmed) as CliJsonOutput;\n\n if (json.is_error || json.error) {\n return {\n success: false,\n output: json.result ?? json.output ?? '',\n error: json.error ?? 'Unknown CLI error',\n costUsd: json.cost_usd,\n };\n }\n\n return {\n success: true,\n output: json.result ?? json.output ?? trimmed,\n costUsd: json.cost_usd,\n };\n } catch {\n // Not valid JSON — treat as raw text output\n return {\n success: true,\n output: trimmed,\n };\n }\n}\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Invoke Claude to process a prompt.\n *\n * When `COLESLAW_MOCK=1` is set or the `claude` CLI is not available on PATH,\n * this automatically falls back to a mock implementation with a warning log.\n */\nexport async function invokeClaude(options: InvokeOptions): Promise<InvokeResult> {\n if (isMockMode()) {\n if (!isClaudeAvailable()) {\n logger.warn('Claude CLI not found on PATH — using mock mode');\n } else {\n logger.info('COLESLAW_MOCK=1 set — using mock mode');\n }\n return invokeMock(options);\n }\n\n return invokeReal(options);\n}\n\n/**\n * Build InvokeOptions from an AgentConfig, a user prompt, and a system prompt.\n *\n * This is a convenience helper that maps the AgentConfig fields into the\n * shape expected by `invokeClaude`.\n */\nexport function buildInvokeOptions(\n config: AgentConfig,\n prompt: string,\n systemPrompt: string,\n cwd?: string,\n): InvokeOptions {\n return {\n prompt,\n systemPrompt,\n allowedTools: config.allowedTools,\n maxTurns: config.maxTurns,\n cwd,\n };\n}\n","import type {\n AgentNode,\n Department,\n TranscriptEntry,\n MeetingStatus,\n MeetingPhase,\n MinutesRecord,\n ActionItem,\n} from '../types/index.js';\nimport { DEFAULT_MEETING_CONFIG } from '../types/index.js';\nimport {\n getMeeting,\n updateMeeting,\n createMinutes,\n} from '../storage/index.js';\nimport { getDb } from '../storage/db.js';\nimport { getLeaderSystemPrompt } from '../agents/leader-prompts.js';\nimport { createAgentConfig } from '../agents/agent-factory.js';\nimport { invokeClaude, buildInvokeOptions } from '../agents/claude-invoker.js';\nimport { eventBus } from './event-bus.js';\nimport { logger } from '../utils/logger.js';\n\n// ---------------------------------------------------------------------------\n// Agent query — uses Claude CLI or falls back to mock\n// ---------------------------------------------------------------------------\n\ninterface AgentQueryConfig {\n role: string;\n department: Department;\n systemPrompt: string;\n}\n\n/**\n * Query a Claude agent via the CLI subprocess invoker.\n *\n * When COLESLAW_MOCK=1 is set or the `claude` CLI is not available, this\n * automatically falls back to mock responses inside `invokeClaude`.\n */\nasync function queryAgent(config: AgentQueryConfig, prompt: string): Promise<string> {\n const agentConfig = createAgentConfig({\n tier: 'leader',\n role: config.role,\n department: config.department,\n });\n\n const invokeOpts = buildInvokeOptions(\n agentConfig,\n prompt,\n config.systemPrompt,\n );\n\n // Leaders get a 10-minute timeout\n invokeOpts.timeoutMs = 600_000;\n\n const result = await invokeClaude(invokeOpts);\n\n if (!result.success) {\n logger.warn(`Agent query failed for ${config.role}: ${result.error}`);\n // Return the error as content so the meeting can continue\n return `[Error from ${config.role}] ${result.error ?? 'Unknown error during agent invocation'}`;\n }\n\n return result.output;\n}\n\n// ---------------------------------------------------------------------------\n// Transcript helpers (direct DB access since there is no transcript store)\n// ---------------------------------------------------------------------------\n\nfunction insertTranscriptEntry(\n meetingId: string,\n speakerId: string,\n speakerRole: string,\n agendaItemIndex: number,\n roundNumber: number,\n content: string,\n): TranscriptEntry {\n const db = getDb();\n const now = Date.now();\n const tokenCount = Math.ceil(content.length / 4); // rough approximation\n\n const result = db\n .prepare(\n `INSERT INTO transcript_entries\n (meeting_id, speaker_id, speaker_role, agenda_item_index, round_number, content, token_count, created_at)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?)`,\n )\n .run(meetingId, speakerId, speakerRole, agendaItemIndex, roundNumber, content, tokenCount, now);\n\n return {\n id: Number(result.lastInsertRowid),\n meetingId,\n speakerId,\n speakerRole,\n agendaItemIndex,\n roundNumber,\n content,\n tokenCount,\n createdAt: now,\n };\n}\n\nfunction getTranscript(meetingId: string): TranscriptEntry[] {\n const db = getDb();\n interface TranscriptRow {\n id: number;\n meeting_id: string;\n speaker_id: string;\n speaker_role: string;\n agenda_item_index: number;\n round_number: number;\n content: string;\n token_count: number;\n created_at: number;\n }\n const rows = db\n .prepare('SELECT * FROM transcript_entries WHERE meeting_id = ? ORDER BY created_at ASC')\n .all(meetingId) as TranscriptRow[];\n\n return rows.map((r) => ({\n id: r.id,\n meetingId: r.meeting_id,\n speakerId: r.speaker_id,\n speakerRole: r.speaker_role,\n agendaItemIndex: r.agenda_item_index,\n roundNumber: r.round_number,\n content: r.content,\n tokenCount: r.token_count,\n createdAt: r.created_at,\n }));\n}\n\n// ---------------------------------------------------------------------------\n// MeetingRunner\n// ---------------------------------------------------------------------------\n\nexport class MeetingRunner {\n private readonly meetingId: string;\n private readonly leaders: AgentNode[];\n private readonly maxRoundsPerItem: number;\n private readonly projectContext: string | undefined;\n\n constructor(meetingId: string, leaders: AgentNode[], projectContext?: string) {\n this.meetingId = meetingId;\n this.leaders = leaders;\n this.maxRoundsPerItem = DEFAULT_MEETING_CONFIG.maxRoundsPerItem;\n this.projectContext = projectContext;\n }\n\n // ---- public entry point -------------------------------------------------\n\n /**\n * Run the complete meeting lifecycle: opening -> discussion -> synthesis -> minutes.\n */\n async run(): Promise<void> {\n const meeting = getMeeting(this.meetingId);\n if (!meeting) {\n throw new Error(`Meeting not found: ${this.meetingId}`);\n }\n\n logger.info(`Starting meeting: ${meeting.topic}`, { meetingId: this.meetingId });\n\n try {\n await this.openingPhase();\n await this.discussionPhase();\n await this.synthesisPhase();\n await this.generateMinutes();\n\n updateMeeting(this.meetingId, {\n status: 'completed' as MeetingStatus,\n completedAt: Date.now(),\n });\n\n logger.info(`Meeting completed: ${meeting.topic}`, { meetingId: this.meetingId });\n } catch (err) {\n const errorMsg = err instanceof Error ? err.message : String(err);\n logger.error(`Meeting failed: ${errorMsg}`, { meetingId: this.meetingId });\n\n updateMeeting(this.meetingId, {\n status: 'failed' as MeetingStatus,\n completedAt: Date.now(),\n });\n\n throw err;\n }\n }\n\n // ---- phases -------------------------------------------------------------\n\n /**\n * Opening phase: each leader states their initial position on the meeting\n * topic and agenda.\n */\n private async openingPhase(): Promise<void> {\n this.setPhase('opening');\n\n const meeting = getMeeting(this.meetingId)!;\n const agendaText = meeting.agenda.map((a, i) => ` ${i + 1}. ${a}`).join('\\n');\n\n for (const leader of this.leaders) {\n const prompt =\n `MEETING OPENING\\n\\n` +\n `Topic: ${meeting.topic}\\n` +\n `Agenda:\\n${agendaText}\\n\\n` +\n `Please state your initial position on this topic from your department's perspective. ` +\n `Identify any concerns, dependencies, or risks relevant to your area.`;\n\n const config: AgentQueryConfig = {\n role: leader.role,\n department: leader.department,\n systemPrompt: getLeaderSystemPrompt(leader.department, undefined, this.projectContext),\n };\n\n const response = await queryAgent(config, prompt);\n\n insertTranscriptEntry(\n this.meetingId,\n leader.id,\n leader.role,\n -1, // -1 signals the opening phase (not tied to a specific agenda item)\n 0,\n response,\n );\n\n eventBus.emitAgentEvent({\n kind: 'message_sent',\n fromId: leader.id,\n toId: 'meeting',\n summary: `[Opening] ${leader.role}: ${response.slice(0, 80)}...`,\n });\n\n logger.debug(`Opening statement from ${leader.role}`, {\n meetingId: this.meetingId,\n agentId: leader.id,\n });\n }\n }\n\n /**\n * Discussion phase: for each agenda item, leaders take turns responding in\n * round-robin fashion for up to `maxRoundsPerItem` rounds.\n */\n private async discussionPhase(): Promise<void> {\n this.setPhase('discussion');\n\n const meeting = getMeeting(this.meetingId)!;\n\n for (let itemIdx = 0; itemIdx < meeting.agenda.length; itemIdx++) {\n const agendaItem = meeting.agenda[itemIdx];\n\n logger.info(`Discussing agenda item ${itemIdx + 1}: ${agendaItem}`, {\n meetingId: this.meetingId,\n });\n\n for (let round = 1; round <= this.maxRoundsPerItem; round++) {\n for (const leader of this.leaders) {\n // Build the prompt with full transcript context\n const transcript = getTranscript(this.meetingId);\n const transcriptText = this.formatTranscript(transcript);\n\n const prompt =\n `MEETING DISCUSSION — Round ${round}/${this.maxRoundsPerItem}\\n\\n` +\n `Current agenda item (${itemIdx + 1}/${meeting.agenda.length}): ${agendaItem}\\n\\n` +\n `Transcript so far:\\n${transcriptText}\\n\\n` +\n `Provide your department's perspective on this agenda item. ` +\n `Build on what others have said. If you agree, say so and add specifics. ` +\n `If you disagree, state your reasoning and propose an alternative.`;\n\n const config: AgentQueryConfig = {\n role: leader.role,\n department: leader.department,\n systemPrompt: getLeaderSystemPrompt(leader.department, undefined, this.projectContext),\n };\n\n const response = await queryAgent(config, prompt);\n\n insertTranscriptEntry(\n this.meetingId,\n leader.id,\n leader.role,\n itemIdx,\n round,\n response,\n );\n\n eventBus.emitAgentEvent({\n kind: 'message_sent',\n fromId: leader.id,\n toId: 'meeting',\n summary: `[Item ${itemIdx + 1}, R${round}] ${leader.role}: ${response.slice(0, 80)}...`,\n });\n }\n }\n }\n }\n\n /**\n * Synthesis phase: each leader states their final position, commitments,\n * and action items.\n */\n private async synthesisPhase(): Promise<void> {\n this.setPhase('synthesis');\n\n const transcript = getTranscript(this.meetingId);\n const transcriptText = this.formatTranscript(transcript);\n\n for (const leader of this.leaders) {\n const prompt =\n `MEETING SYNTHESIS\\n\\n` +\n `The discussion is complete. Here is the full transcript:\\n${transcriptText}\\n\\n` +\n `State your final position. List the action items your department commits to. ` +\n `Flag any unresolved concerns or items requiring user decision.`;\n\n const config: AgentQueryConfig = {\n role: leader.role,\n department: leader.department,\n systemPrompt: getLeaderSystemPrompt(leader.department, undefined, this.projectContext),\n };\n\n const response = await queryAgent(config, prompt);\n\n insertTranscriptEntry(\n this.meetingId,\n leader.id,\n leader.role,\n -2, // -2 signals synthesis phase\n 0,\n response,\n );\n\n eventBus.emitAgentEvent({\n kind: 'message_sent',\n fromId: leader.id,\n toId: 'meeting',\n summary: `[Synthesis] ${leader.role}: ${response.slice(0, 80)}...`,\n });\n }\n }\n\n /**\n * Generate meeting minutes by concatenating and formatting the transcript.\n *\n * In the future this will use a dedicated minutes-writer agent. For now it\n * formats the transcript into a structured summary.\n */\n private async generateMinutes(): Promise<void> {\n this.setPhase('minutes-generation');\n\n const meeting = getMeeting(this.meetingId)!;\n const transcript = getTranscript(this.meetingId);\n\n // --- Build the minutes content ---\n\n const sections: string[] = [];\n\n sections.push(`# Meeting Minutes`);\n sections.push(`## Topic: ${meeting.topic}`);\n sections.push(`## Date: ${new Date().toISOString()}`);\n sections.push(`## Participants: ${this.leaders.map((l) => l.role).join(', ')}`);\n sections.push('');\n\n // Agenda\n sections.push(`## Agenda`);\n meeting.agenda.forEach((item, i) => {\n sections.push(`${i + 1}. ${item}`);\n });\n sections.push('');\n\n // Opening statements\n const openingEntries = transcript.filter((e) => e.agendaItemIndex === -1);\n if (openingEntries.length > 0) {\n sections.push(`## Opening Statements`);\n for (const entry of openingEntries) {\n sections.push(`### ${entry.speakerRole}`);\n sections.push(entry.content);\n sections.push('');\n }\n }\n\n // Discussion per agenda item\n for (let i = 0; i < meeting.agenda.length; i++) {\n const itemEntries = transcript.filter((e) => e.agendaItemIndex === i);\n if (itemEntries.length > 0) {\n sections.push(`## Discussion: ${meeting.agenda[i]}`);\n for (const entry of itemEntries) {\n sections.push(`**${entry.speakerRole}** (round ${entry.roundNumber}):`);\n sections.push(entry.content);\n sections.push('');\n }\n }\n }\n\n // Synthesis\n const synthesisEntries = transcript.filter((e) => e.agendaItemIndex === -2);\n if (synthesisEntries.length > 0) {\n sections.push(`## Final Positions`);\n for (const entry of synthesisEntries) {\n sections.push(`### ${entry.speakerRole}`);\n sections.push(entry.content);\n sections.push('');\n }\n }\n\n const content = sections.join('\\n');\n\n // --- Extract action items from synthesis entries ---\n\n const actionItems: ActionItem[] = this.leaders.map((leader, idx) => ({\n id: `action-${this.meetingId}-${idx}`,\n title: `${leader.role} deliverables`,\n description: `Action items committed by ${leader.role} during synthesis phase`,\n assignedDepartment: leader.department,\n assignedRole: leader.role,\n priority: 'medium' as const,\n dependencies: [],\n acceptanceCriteria: ['Deliverables completed as stated in final position'],\n }));\n\n createMinutes({\n meetingId: this.meetingId,\n format: 'summary',\n content,\n actionItems,\n });\n\n logger.info('Minutes generated', { meetingId: this.meetingId });\n }\n\n // ---- helpers ------------------------------------------------------------\n\n private setPhase(phase: MeetingPhase): void {\n const statusMap: Record<MeetingPhase, MeetingStatus> = {\n 'orchestrator-phase': 'pending',\n 'convening': 'convening',\n 'opening': 'opening',\n 'discussion': 'discussion',\n 'research-break': 'discussion',\n 'synthesis': 'synthesis',\n 'minutes-generation': 'minutes-generation',\n };\n\n updateMeeting(this.meetingId, {\n phase,\n status: statusMap[phase] ?? 'discussion',\n });\n\n logger.debug(`Meeting phase: ${phase}`, { meetingId: this.meetingId });\n }\n\n private formatTranscript(entries: TranscriptEntry[]): string {\n if (entries.length === 0) return '(No transcript entries yet)';\n\n return entries\n .map((e) => {\n let phaseLabel: string;\n if (e.agendaItemIndex === -1) phaseLabel = 'Opening';\n else if (e.agendaItemIndex === -2) phaseLabel = 'Synthesis';\n else phaseLabel = `Item ${e.agendaItemIndex + 1}, Round ${e.roundNumber}`;\n return `[${phaseLabel}] ${e.speakerRole}: ${e.content}`;\n })\n .join('\\n\\n');\n }\n}\n","import { existsSync, readFileSync, readdirSync, statSync } from 'node:fs';\nimport { join, basename, extname } from 'node:path';\nimport { logger } from '../utils/logger.js';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport type ProjectLanguage =\n | 'javascript'\n | 'typescript'\n | 'python'\n | 'java'\n | 'kotlin'\n | 'go'\n | 'rust'\n | 'swift'\n | 'dart'\n | 'ruby'\n | 'csharp'\n | 'cpp'\n | 'unknown';\n\n/** Language-agnostic dependency info extracted from any manifest file. */\nexport interface DependencyManifest {\n file: string; // e.g. \"package.json\", \"build.gradle.kts\"\n language: ProjectLanguage;\n dependencies: Record<string, string>; // name -> version/spec\n devDependencies: Record<string, string>;\n scripts: Record<string, string>; // build/test/run commands\n metadata: Record<string, string>; // language-specific extras\n}\n\nexport interface ProjectAnalysis {\n /** Primary language detected. */\n language: ProjectLanguage;\n\n /** All dependency manifests found (can be multi-language monorepo). */\n manifests: DependencyManifest[];\n\n /** Parsed package.json contents, or null if not found. (Kept for backward compat.) */\n packageJson: {\n name: string;\n dependencies: Record<string, string>;\n devDependencies: Record<string, string>;\n scripts: Record<string, string>;\n type?: string; // \"module\" or \"commonjs\"\n } | null;\n\n /** High-level project structure signals. */\n structure: {\n hasTypescript: boolean;\n hasSrcDir: boolean;\n hasTestDir: boolean;\n configFiles: string[]; // tsconfig, eslint, prettier, etc.\n entryPoints: string[];\n };\n\n /** Detected coding patterns and tooling. */\n patterns: {\n importStyle: 'esm' | 'commonjs' | 'mixed';\n testFramework: string | null; // vitest, jest, mocha, etc.\n linter: string | null; // eslint, biome, etc.\n formatter: string | null; // prettier, biome, etc.\n buildTool: string | null; // tsup, esbuild, webpack, vite, etc.\n };\n\n /** Existing utility files and their named exports. */\n existingUtils: {\n file: string;\n exports: string[];\n }[];\n}\n\n// ---------------------------------------------------------------------------\n// Config-file detection lists\n// ---------------------------------------------------------------------------\n\nconst CONFIG_FILE_PATTERNS: string[] = [\n 'tsconfig.json',\n 'tsconfig.build.json',\n 'tsconfig.node.json',\n '.eslintrc',\n '.eslintrc.js',\n '.eslintrc.cjs',\n '.eslintrc.json',\n '.eslintrc.yml',\n '.eslintrc.yaml',\n 'eslint.config.js',\n 'eslint.config.mjs',\n 'eslint.config.cjs',\n 'eslint.config.ts',\n '.prettierrc',\n '.prettierrc.js',\n '.prettierrc.cjs',\n '.prettierrc.json',\n '.prettierrc.yml',\n '.prettierrc.yaml',\n 'prettier.config.js',\n 'prettier.config.mjs',\n 'prettier.config.cjs',\n 'biome.json',\n 'biome.jsonc',\n 'vite.config.ts',\n 'vite.config.js',\n 'vite.config.mjs',\n 'webpack.config.js',\n 'webpack.config.ts',\n 'webpack.config.mjs',\n 'rollup.config.js',\n 'rollup.config.ts',\n 'rollup.config.mjs',\n 'tsup.config.ts',\n 'tsup.config.js',\n 'esbuild.config.js',\n 'esbuild.config.ts',\n 'jest.config.js',\n 'jest.config.ts',\n 'jest.config.mjs',\n 'vitest.config.ts',\n 'vitest.config.js',\n 'vitest.config.mts',\n '.mocharc.yml',\n '.mocharc.json',\n '.mocharc.js',\n '.babelrc',\n 'babel.config.js',\n 'babel.config.json',\n '.swcrc',\n 'turbo.json',\n 'nx.json',\n];\n\n/** Directories that commonly house reusable utility code. */\nconst UTIL_DIR_NAMES = ['utils', 'lib', 'helpers', 'shared', 'common'];\n\n/** Language-specific dependency manifest files and how to parse them. */\nconst MANIFEST_FILES: {\n file: string;\n language: ProjectLanguage;\n parse: (content: string, projectDir: string) => Omit<DependencyManifest, 'file' | 'language'>;\n}[] = [\n // -- JavaScript / TypeScript --\n {\n file: 'package.json',\n language: 'typescript', // refined later if no TS config\n parse: (content) => {\n const raw = JSON.parse(content);\n return {\n dependencies: raw.dependencies ?? {},\n devDependencies: raw.devDependencies ?? {},\n scripts: raw.scripts ?? {},\n metadata: { type: raw.type ?? 'commonjs', name: raw.name ?? '' },\n };\n },\n },\n // -- Python --\n {\n file: 'pyproject.toml',\n language: 'python',\n parse: (content) => {\n const deps: Record<string, string> = {};\n const devDeps: Record<string, string> = {};\n const scripts: Record<string, string> = {};\n // Parse [project.dependencies]\n for (const m of content.matchAll(/^\\s*\"([^\"]+?)(?:[><=!~]+.*)?\".*$/gm)) {\n deps[m[1]] = '*';\n }\n // Parse [project.scripts]\n for (const m of content.matchAll(/^(\\w[\\w-]*)\\s*=\\s*\"([^\"]+)\"/gm)) {\n scripts[m[1]] = m[2];\n }\n return { dependencies: deps, devDependencies: devDeps, scripts, metadata: {} };\n },\n },\n {\n file: 'requirements.txt',\n language: 'python',\n parse: (content) => {\n const deps: Record<string, string> = {};\n for (const line of content.split('\\n')) {\n const trimmed = line.trim();\n if (!trimmed || trimmed.startsWith('#') || trimmed.startsWith('-')) continue;\n const match = trimmed.match(/^([a-zA-Z0-9_-]+)\\s*([><=!~].*)?$/);\n if (match) deps[match[1]] = match[2]?.trim() ?? '*';\n }\n return { dependencies: deps, devDependencies: {}, scripts: {}, metadata: {} };\n },\n },\n {\n file: 'Pipfile',\n language: 'python',\n parse: (content) => {\n const deps: Record<string, string> = {};\n const inPackages = content.indexOf('[packages]');\n if (inPackages >= 0) {\n const section = content.slice(inPackages);\n for (const m of section.matchAll(/^(\\w[\\w-]*)\\s*=\\s*\"([^\"]+)\"/gm)) {\n deps[m[1]] = m[2];\n }\n }\n return { dependencies: deps, devDependencies: {}, scripts: {}, metadata: {} };\n },\n },\n // -- Java / Kotlin (Gradle) --\n {\n file: 'build.gradle',\n language: 'java',\n parse: (content) => {\n const deps: Record<string, string> = {};\n // implementation 'group:artifact:version'\n for (const m of content.matchAll(/(?:implementation|api|compileOnly)\\s+['\"]([^'\"]+)['\"]/g)) {\n const parts = m[1].split(':');\n if (parts.length >= 2) deps[`${parts[0]}:${parts[1]}`] = parts[2] ?? '*';\n }\n return { dependencies: deps, devDependencies: {}, scripts: {}, metadata: { buildSystem: 'gradle' } };\n },\n },\n {\n file: 'build.gradle.kts',\n language: 'kotlin',\n parse: (content) => {\n const deps: Record<string, string> = {};\n for (const m of content.matchAll(/(?:implementation|api|compileOnly)\\s*\\(\\s*\"([^\"]+)\"\\s*\\)/g)) {\n const parts = m[1].split(':');\n if (parts.length >= 2) deps[`${parts[0]}:${parts[1]}`] = parts[2] ?? '*';\n }\n return { dependencies: deps, devDependencies: {}, scripts: {}, metadata: { buildSystem: 'gradle-kts' } };\n },\n },\n {\n file: 'pom.xml',\n language: 'java',\n parse: (content) => {\n const deps: Record<string, string> = {};\n for (const m of content.matchAll(/<dependency>\\s*<groupId>([^<]+)<\\/groupId>\\s*<artifactId>([^<]+)<\\/artifactId>(?:\\s*<version>([^<]+)<\\/version>)?/gs)) {\n deps[`${m[1]}:${m[2]}`] = m[3] ?? '*';\n }\n return { dependencies: deps, devDependencies: {}, scripts: {}, metadata: { buildSystem: 'maven' } };\n },\n },\n // -- Go --\n {\n file: 'go.mod',\n language: 'go',\n parse: (content) => {\n const deps: Record<string, string> = {};\n for (const m of content.matchAll(/^\\s+(\\S+)\\s+(v[\\d.]+\\S*)/gm)) {\n deps[m[1]] = m[2];\n }\n const moduleMatch = content.match(/^module\\s+(\\S+)/m);\n return { dependencies: deps, devDependencies: {}, scripts: {}, metadata: { module: moduleMatch?.[1] ?? '' } };\n },\n },\n // -- Rust --\n {\n file: 'Cargo.toml',\n language: 'rust',\n parse: (content) => {\n const deps: Record<string, string> = {};\n const devDeps: Record<string, string> = {};\n let inDeps = false;\n let inDevDeps = false;\n for (const line of content.split('\\n')) {\n if (line.match(/^\\[dependencies\\]/)) { inDeps = true; inDevDeps = false; continue; }\n if (line.match(/^\\[dev-dependencies\\]/)) { inDevDeps = true; inDeps = false; continue; }\n if (line.match(/^\\[/)) { inDeps = false; inDevDeps = false; continue; }\n const m = line.match(/^(\\w[\\w-]*)\\s*=\\s*\"([^\"]+)\"/);\n if (m) {\n if (inDeps) deps[m[1]] = m[2];\n if (inDevDeps) devDeps[m[1]] = m[2];\n }\n }\n return { dependencies: deps, devDependencies: devDeps, scripts: {}, metadata: {} };\n },\n },\n // -- Swift --\n {\n file: 'Package.swift',\n language: 'swift',\n parse: (content) => {\n const deps: Record<string, string> = {};\n for (const m of content.matchAll(/\\.package\\s*\\(\\s*url:\\s*\"([^\"]+)\"/g)) {\n const name = m[1].split('/').pop()?.replace('.git', '') ?? m[1];\n deps[name] = '*';\n }\n return { dependencies: deps, devDependencies: {}, scripts: {}, metadata: {} };\n },\n },\n // -- Dart / Flutter --\n {\n file: 'pubspec.yaml',\n language: 'dart',\n parse: (content) => {\n const deps: Record<string, string> = {};\n let inDeps = false;\n for (const line of content.split('\\n')) {\n if (line.match(/^dependencies:/)) { inDeps = true; continue; }\n if (line.match(/^\\S/) && inDeps) { inDeps = false; continue; }\n if (inDeps) {\n const m = line.match(/^\\s+(\\w[\\w_-]*):\\s*(.+)?/);\n if (m) deps[m[1]] = m[2]?.trim() ?? '*';\n }\n }\n return { dependencies: deps, devDependencies: {}, scripts: {}, metadata: {} };\n },\n },\n // -- Ruby --\n {\n file: 'Gemfile',\n language: 'ruby',\n parse: (content) => {\n const deps: Record<string, string> = {};\n for (const m of content.matchAll(/gem\\s+['\"]([^'\"]+)['\"]/g)) {\n deps[m[1]] = '*';\n }\n return { dependencies: deps, devDependencies: {}, scripts: {}, metadata: {} };\n },\n },\n // -- C# / .NET --\n {\n file: '*.csproj', // handled specially in the scanner\n language: 'csharp',\n parse: (content) => {\n const deps: Record<string, string> = {};\n for (const m of content.matchAll(/<PackageReference\\s+Include=\"([^\"]+)\"\\s+Version=\"([^\"]+)\"/g)) {\n deps[m[1]] = m[2];\n }\n return { dependencies: deps, devDependencies: {}, scripts: {}, metadata: { buildSystem: 'dotnet' } };\n },\n },\n];\n\n/** Detect project language from found manifests. */\nfunction detectLanguage(projectDir: string, manifests: DependencyManifest[]): ProjectLanguage {\n if (manifests.length === 0) return 'unknown';\n\n // If there's a tsconfig, it's TypeScript regardless\n if (existsSync(join(projectDir, 'tsconfig.json'))) return 'typescript';\n\n // Use the first manifest's language as primary\n const languages = manifests.map((m) => m.language);\n if (languages.includes('typescript')) return 'typescript';\n if (languages.includes('kotlin')) return 'kotlin';\n\n return languages[0];\n}\n\n/** Scan for all dependency manifests in a project. */\nfunction scanManifests(projectDir: string): DependencyManifest[] {\n const results: DependencyManifest[] = [];\n\n for (const spec of MANIFEST_FILES) {\n // Handle glob pattern (*.csproj)\n if (spec.file.includes('*')) {\n const ext = spec.file.replace('*', '');\n try {\n const entries = readdirSync(projectDir);\n for (const entry of entries) {\n if (entry.endsWith(ext)) {\n const content = readFileSync(join(projectDir, entry), 'utf-8');\n try {\n const parsed = spec.parse(content, projectDir);\n results.push({ file: entry, language: spec.language, ...parsed });\n } catch { /* skip malformed */ }\n }\n }\n } catch { /* skip */ }\n continue;\n }\n\n const filePath = join(projectDir, spec.file);\n if (!existsSync(filePath)) continue;\n\n try {\n const content = readFileSync(filePath, 'utf-8');\n const parsed = spec.parse(content, projectDir);\n results.push({ file: spec.file, language: spec.language, ...parsed });\n } catch {\n logger.debug(`Failed to parse manifest: ${spec.file}`);\n }\n }\n\n return results;\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction readJsonSafe(filePath: string): unknown | null {\n try {\n const raw = readFileSync(filePath, 'utf-8');\n return JSON.parse(raw);\n } catch {\n return null;\n }\n}\n\n/** Collect named exports from a .ts or .js file using lightweight regex. */\nfunction extractExports(filePath: string): string[] {\n try {\n const content = readFileSync(filePath, 'utf-8');\n const exports: string[] = [];\n\n // export function foo\n for (const m of content.matchAll(/export\\s+(?:async\\s+)?function\\s+(\\w+)/g)) {\n exports.push(m[1]);\n }\n // export class Foo\n for (const m of content.matchAll(/export\\s+class\\s+(\\w+)/g)) {\n exports.push(m[1]);\n }\n // export const/let/var foo\n for (const m of content.matchAll(/export\\s+(?:const|let|var)\\s+(\\w+)/g)) {\n exports.push(m[1]);\n }\n // export interface Foo / export type Foo\n for (const m of content.matchAll(/export\\s+(?:interface|type)\\s+(\\w+)/g)) {\n exports.push(m[1]);\n }\n // export enum Foo\n for (const m of content.matchAll(/export\\s+enum\\s+(\\w+)/g)) {\n exports.push(m[1]);\n }\n // export default (just record \"default\")\n if (/export\\s+default\\s/.test(content)) {\n exports.push('default');\n }\n\n return [...new Set(exports)];\n } catch {\n return [];\n }\n}\n\n/** Sample up to N .ts/.js files from a directory tree (non-recursive beyond 2 levels). */\nfunction sampleSourceFiles(dir: string, max: number): string[] {\n const results: string[] = [];\n const extensions = new Set(['.ts', '.js', '.mts', '.mjs', '.cts', '.cjs']);\n\n function walk(currentDir: string, depth: number): void {\n if (depth > 2 || results.length >= max) return;\n let entries: string[];\n try {\n entries = readdirSync(currentDir);\n } catch {\n return;\n }\n for (const entry of entries) {\n if (results.length >= max) return;\n if (entry.startsWith('.') || entry === 'node_modules' || entry === 'dist') continue;\n const full = join(currentDir, entry);\n try {\n const stat = statSync(full);\n if (stat.isDirectory()) {\n walk(full, depth + 1);\n } else if (stat.isFile() && extensions.has(extname(entry))) {\n results.push(full);\n }\n } catch {\n // Skip inaccessible entries\n }\n }\n }\n\n walk(dir, 0);\n return results;\n}\n\n/** Detect import style by scanning a few source files. */\nfunction detectImportStyle(\n projectDir: string,\n packageType: string | undefined,\n): 'esm' | 'commonjs' | 'mixed' {\n const sourceDir = existsSync(join(projectDir, 'src'))\n ? join(projectDir, 'src')\n : projectDir;\n\n const files = sampleSourceFiles(sourceDir, 10);\n let esmCount = 0;\n let cjsCount = 0;\n\n for (const file of files) {\n try {\n const content = readFileSync(file, 'utf-8');\n if (/\\bimport\\s+/.test(content) || /\\bexport\\s+/.test(content)) {\n esmCount++;\n }\n if (/\\brequire\\s*\\(/.test(content) || /\\bmodule\\.exports\\b/.test(content)) {\n cjsCount++;\n }\n } catch {\n // skip\n }\n }\n\n // If we have no signal from files, fall back to package.json \"type\"\n if (esmCount === 0 && cjsCount === 0) {\n return packageType === 'module' ? 'esm' : 'commonjs';\n }\n\n if (esmCount > 0 && cjsCount > 0) return 'mixed';\n if (esmCount > 0) return 'esm';\n return 'commonjs';\n}\n\nfunction detectTestFramework(deps: Record<string, string>): string | null {\n const candidates: [string, string][] = [\n ['vitest', 'vitest'],\n ['jest', 'jest'],\n ['@jest/core', 'jest'],\n ['mocha', 'mocha'],\n ['ava', 'ava'],\n ['tap', 'tap'],\n ['uvu', 'uvu'],\n ];\n for (const [pkg, name] of candidates) {\n if (pkg in deps) return name;\n }\n return null;\n}\n\nfunction detectLinter(deps: Record<string, string>, configFiles: string[]): string | null {\n if ('biome' in deps || '@biomejs/biome' in deps || configFiles.some((f) => f.startsWith('biome.'))) {\n return 'biome';\n }\n if ('eslint' in deps || configFiles.some((f) => f.includes('eslint'))) {\n return 'eslint';\n }\n return null;\n}\n\nfunction detectFormatter(deps: Record<string, string>, configFiles: string[]): string | null {\n // Biome also formats — if it is the linter and prettier is absent, biome is the formatter\n if ('prettier' in deps || configFiles.some((f) => f.includes('prettier'))) {\n return 'prettier';\n }\n if ('biome' in deps || '@biomejs/biome' in deps || configFiles.some((f) => f.startsWith('biome.'))) {\n return 'biome';\n }\n return null;\n}\n\nfunction detectBuildTool(\n deps: Record<string, string>,\n scripts: Record<string, string>,\n): string | null {\n const candidates: [string, string][] = [\n ['tsup', 'tsup'],\n ['esbuild', 'esbuild'],\n ['vite', 'vite'],\n ['webpack', 'webpack'],\n ['rollup', 'rollup'],\n ['@swc/core', 'swc'],\n ['turbopack', 'turbopack'],\n ['parcel', 'parcel'],\n ];\n\n for (const [pkg, name] of candidates) {\n if (pkg in deps) return name;\n }\n\n // Fallback: check build script content\n const buildScript = scripts['build'] ?? '';\n for (const [, name] of candidates) {\n if (buildScript.includes(name)) return name;\n }\n\n // tsc-only builds\n if (buildScript.includes('tsc')) return 'tsc';\n\n return null;\n}\n\nfunction detectEntryPoints(\n projectDir: string,\n packageJson: ProjectAnalysis['packageJson'],\n): string[] {\n const entries: string[] = [];\n\n if (packageJson) {\n // \"main\" field\n const raw = readJsonSafe(join(projectDir, 'package.json')) as Record<string, unknown> | null;\n if (raw) {\n if (typeof raw['main'] === 'string') entries.push(raw['main']);\n if (typeof raw['module'] === 'string') entries.push(raw['module']);\n if (raw['exports'] && typeof raw['exports'] === 'object') {\n const exp = raw['exports'] as Record<string, unknown>;\n // Check \".\" entry\n const dot = exp['.'];\n if (typeof dot === 'string') {\n entries.push(dot);\n } else if (dot && typeof dot === 'object') {\n const dotObj = dot as Record<string, unknown>;\n if (typeof dotObj['import'] === 'string') entries.push(dotObj['import']);\n if (typeof dotObj['require'] === 'string') entries.push(dotObj['require']);\n }\n }\n }\n }\n\n // Common default entry points\n const commonEntries = ['src/index.ts', 'src/main.ts', 'src/index.js', 'src/main.js', 'index.ts', 'index.js'];\n for (const candidate of commonEntries) {\n if (existsSync(join(projectDir, candidate)) && !entries.includes(candidate)) {\n entries.push(candidate);\n }\n }\n\n return [...new Set(entries)];\n}\n\n/** Collect utility files from well-known directories under src/. */\nfunction collectUtilFiles(projectDir: string): ProjectAnalysis['existingUtils'] {\n const results: ProjectAnalysis['existingUtils'] = [];\n const srcDir = join(projectDir, 'src');\n const extensions = new Set(['.ts', '.js', '.mts', '.mjs']);\n\n for (const dirName of UTIL_DIR_NAMES) {\n const utilDir = join(srcDir, dirName);\n if (!existsSync(utilDir)) continue;\n\n let entries: string[];\n try {\n entries = readdirSync(utilDir);\n } catch {\n continue;\n }\n\n for (const entry of entries) {\n const ext = extname(entry);\n if (!extensions.has(ext)) continue;\n // Skip index files — they are typically re-exports\n if (basename(entry, ext) === 'index') continue;\n\n const filePath = join(utilDir, entry);\n try {\n if (!statSync(filePath).isFile()) continue;\n } catch {\n continue;\n }\n\n const exports = extractExports(filePath);\n if (exports.length > 0) {\n // Store a relative path from projectDir for readability\n const relPath = filePath.slice(projectDir.length + 1);\n results.push({ file: relPath, exports });\n }\n }\n }\n\n return results;\n}\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Analyse a project directory and return structured metadata about its\n * dependencies, tooling, patterns, and existing utilities.\n *\n * This is intentionally lightweight (no AST parsing, limited FS traversal)\n * so it can run before every meeting without noticeable delay.\n */\nexport async function analyzeProject(projectDir: string): Promise<ProjectAnalysis> {\n logger.debug(`Analyzing project: ${projectDir}`);\n\n // 1. Read package.json\n let packageJson: ProjectAnalysis['packageJson'] = null;\n const pkgPath = join(projectDir, 'package.json');\n if (existsSync(pkgPath)) {\n const raw = readJsonSafe(pkgPath) as Record<string, unknown> | null;\n if (raw) {\n packageJson = {\n name: (raw['name'] as string) ?? '',\n dependencies: (raw['dependencies'] as Record<string, string>) ?? {},\n devDependencies: (raw['devDependencies'] as Record<string, string>) ?? {},\n scripts: (raw['scripts'] as Record<string, string>) ?? {},\n type: raw['type'] as string | undefined,\n };\n }\n }\n\n // 2. Detect config files\n const configFiles: string[] = [];\n for (const pattern of CONFIG_FILE_PATTERNS) {\n if (existsSync(join(projectDir, pattern))) {\n configFiles.push(pattern);\n }\n }\n\n // 3. Structure\n const hasTypescript =\n existsSync(join(projectDir, 'tsconfig.json')) ||\n configFiles.some((f) => f.startsWith('tsconfig'));\n const hasSrcDir = existsSync(join(projectDir, 'src'));\n const hasTestDir =\n existsSync(join(projectDir, 'test')) ||\n existsSync(join(projectDir, 'tests')) ||\n existsSync(join(projectDir, '__tests__'));\n const entryPoints = detectEntryPoints(projectDir, packageJson);\n\n const structure: ProjectAnalysis['structure'] = {\n hasTypescript,\n hasSrcDir,\n hasTestDir,\n configFiles,\n entryPoints,\n };\n\n // 4. All deps combined for detection\n const allDeps: Record<string, string> = {\n ...(packageJson?.dependencies ?? {}),\n ...(packageJson?.devDependencies ?? {}),\n };\n\n // 5. Patterns\n const patterns: ProjectAnalysis['patterns'] = {\n importStyle: detectImportStyle(projectDir, packageJson?.type),\n testFramework: detectTestFramework(allDeps),\n linter: detectLinter(allDeps, configFiles),\n formatter: detectFormatter(allDeps, configFiles),\n buildTool: detectBuildTool(allDeps, packageJson?.scripts ?? {}),\n };\n\n // 6. Existing utility files\n const existingUtils = collectUtilFiles(projectDir);\n\n // 7. Scan all language-specific manifests\n const manifests = scanManifests(projectDir);\n\n // 8. Detect primary language\n const language = detectLanguage(projectDir, manifests);\n\n logger.debug(`Project analysis complete: ${packageJson?.name ?? '(unnamed)'}, language: ${language}, manifests: ${manifests.length}`, {\n department: 'research',\n });\n\n return {\n language,\n manifests,\n packageJson,\n structure,\n patterns,\n existingUtils,\n };\n}\n\n/**\n * Format a {@link ProjectAnalysis} into a Markdown summary suitable for\n * injection into agent system prompts.\n */\nexport function formatProjectContext(analysis: ProjectAnalysis): string {\n const sections: string[] = [];\n\n // Header\n sections.push('## Project Context');\n sections.push('');\n sections.push(`**Primary Language:** ${analysis.language}`);\n sections.push('');\n\n // Multi-language manifests (non-JS)\n const nonJsManifests = analysis.manifests.filter((m) => m.file !== 'package.json');\n if (nonJsManifests.length > 0) {\n sections.push('### Dependency Manifests');\n for (const manifest of nonJsManifests) {\n sections.push(`#### ${manifest.file} (${manifest.language})`);\n const depNames = Object.keys(manifest.dependencies);\n if (depNames.length > 0) {\n sections.push(depNames.slice(0, 30).map((d) => `- \\`${d}\\`: ${manifest.dependencies[d]}`).join('\\n'));\n if (depNames.length > 30) sections.push(`- ... and ${depNames.length - 30} more`);\n }\n if (Object.keys(manifest.metadata).length > 0) {\n sections.push(`- Metadata: ${JSON.stringify(manifest.metadata)}`);\n }\n sections.push('');\n }\n }\n\n // Package info (JS/TS — backward compat)\n if (analysis.packageJson) {\n const pkg = analysis.packageJson;\n sections.push(`**Project:** ${pkg.name || '(unnamed)'}`);\n sections.push(`**Module system:** ${pkg.type ?? 'commonjs (default)'}`);\n sections.push('');\n\n // Dependencies\n const depNames = Object.keys(pkg.dependencies);\n if (depNames.length > 0) {\n sections.push('### Dependencies');\n sections.push(depNames.map((d) => `- \\`${d}\\`: ${pkg.dependencies[d]}`).join('\\n'));\n sections.push('');\n }\n\n const devDepNames = Object.keys(pkg.devDependencies);\n if (devDepNames.length > 0) {\n sections.push('### Dev Dependencies');\n sections.push(devDepNames.map((d) => `- \\`${d}\\`: ${pkg.devDependencies[d]}`).join('\\n'));\n sections.push('');\n }\n\n // Scripts\n const scriptEntries = Object.entries(pkg.scripts);\n if (scriptEntries.length > 0) {\n sections.push('### Scripts');\n sections.push(scriptEntries.map(([k, v]) => `- \\`${k}\\`: \\`${v}\\``).join('\\n'));\n sections.push('');\n }\n } else {\n sections.push('*No package.json found.*');\n sections.push('');\n }\n\n // Structure\n sections.push('### Project Structure');\n sections.push(`- TypeScript: ${analysis.structure.hasTypescript ? 'yes' : 'no'}`);\n sections.push(`- src/ directory: ${analysis.structure.hasSrcDir ? 'yes' : 'no'}`);\n sections.push(`- Test directory: ${analysis.structure.hasTestDir ? 'yes' : 'no'}`);\n if (analysis.structure.entryPoints.length > 0) {\n sections.push(`- Entry points: ${analysis.structure.entryPoints.map((e) => `\\`${e}\\``).join(', ')}`);\n }\n if (analysis.structure.configFiles.length > 0) {\n sections.push(`- Config files: ${analysis.structure.configFiles.map((f) => `\\`${f}\\``).join(', ')}`);\n }\n sections.push('');\n\n // Patterns\n sections.push('### Detected Patterns');\n sections.push(`- Import style: **${analysis.patterns.importStyle}**`);\n sections.push(`- Test framework: ${analysis.patterns.testFramework ?? 'none detected'}`);\n sections.push(`- Linter: ${analysis.patterns.linter ?? 'none detected'}`);\n sections.push(`- Formatter: ${analysis.patterns.formatter ?? 'none detected'}`);\n sections.push(`- Build tool: ${analysis.patterns.buildTool ?? 'none detected'}`);\n sections.push('');\n\n // Existing utilities\n if (analysis.existingUtils.length > 0) {\n sections.push('### Existing Utilities (reuse before creating new ones)');\n for (const util of analysis.existingUtils) {\n sections.push(`- **\\`${util.file}\\`**: ${util.exports.map((e) => `\\`${e}\\``).join(', ')}`);\n }\n sections.push('');\n }\n\n // Key guidance\n sections.push('### Key Guidance');\n if (analysis.patterns.importStyle === 'esm') {\n sections.push('- Use ESM imports (`import`/`export`). Use `.js` extensions in relative imports if TypeScript with bundler resolution.');\n } else if (analysis.patterns.importStyle === 'commonjs') {\n sections.push('- Use CommonJS (`require`/`module.exports`).');\n } else {\n sections.push('- Mixed import styles detected. Prefer the dominant style in the module you are editing.');\n }\n if (analysis.packageJson) {\n sections.push('- Do NOT run `npm install` for packages already listed in dependencies or devDependencies.');\n }\n if (analysis.patterns.testFramework) {\n sections.push(`- Write tests using **${analysis.patterns.testFramework}** (already installed).`);\n }\n if (analysis.patterns.buildTool) {\n sections.push(`- Build with **${analysis.patterns.buildTool}** (already configured).`);\n }\n\n return sections.join('\\n');\n}\n","import { z } from 'zod';\nimport {\n getMeeting,\n listMeetings,\n listAgentsByMeeting,\n listWorkersByLeader,\n} from '../storage/index.js';\n\nexport const getMeetingStatusSchema = {\n meetingId: z\n .string()\n .optional()\n .describe('Specific meeting ID, or omit for all active'),\n};\n\nexport async function getMeetingStatusHandler({\n meetingId,\n}: {\n meetingId?: string;\n}): Promise<{ content: { type: 'text'; text: string }[]; isError?: boolean }> {\n try {\n if (meetingId) {\n const meeting = getMeeting(meetingId);\n if (!meeting) {\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(\n { error: `Meeting not found: ${meetingId}` },\n null,\n 2,\n ),\n },\n ],\n isError: true,\n };\n }\n\n const agents = listAgentsByMeeting(meetingId);\n const workers = agents.flatMap((agent) =>\n listWorkersByLeader(agent.id),\n );\n\n const result = {\n meeting,\n agents,\n workers,\n };\n\n return {\n content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],\n };\n }\n\n // Return all active meetings summary\n const allMeetings = listMeetings();\n const activeMeetings = allMeetings.filter(\n (m) =>\n !['completed', 'cancelled', 'failed', 'reported', 'compacted'].includes(\n m.status,\n ),\n );\n\n const result = {\n totalMeetings: allMeetings.length,\n activeMeetings: activeMeetings.map((m) => ({\n id: m.id,\n topic: m.topic,\n status: m.status,\n phase: m.phase,\n startedAt: m.startedAt,\n })),\n };\n\n return {\n content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],\n };\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n return {\n content: [\n { type: 'text', text: JSON.stringify({ error: message }, null, 2) },\n ],\n isError: true,\n };\n }\n}\n","import { z } from 'zod';\nimport { getMinutesByMeeting } from '../storage/index.js';\n\nexport const getMinutesSchema = {\n meetingId: z.string().describe('Meeting ID'),\n format: z\n .enum(['full', 'summary', 'tasks_only'])\n .default('full')\n .optional()\n .describe('Output format'),\n};\n\nexport async function getMinutesHandler({\n meetingId,\n format,\n}: {\n meetingId: string;\n format?: 'full' | 'summary' | 'tasks_only';\n}): Promise<{ content: { type: 'text'; text: string }[]; isError?: boolean }> {\n try {\n const minutes = getMinutesByMeeting(meetingId);\n if (!minutes) {\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(\n { error: `No minutes found for meeting: ${meetingId}` },\n null,\n 2,\n ),\n },\n ],\n isError: true,\n };\n }\n\n const effectiveFormat = format ?? 'full';\n\n let result: unknown;\n\n switch (effectiveFormat) {\n case 'full':\n result = {\n id: minutes.id,\n meetingId: minutes.meetingId,\n format: minutes.format,\n content: minutes.content,\n actionItems: minutes.actionItems,\n createdAt: minutes.createdAt,\n };\n break;\n\n case 'summary': {\n // Extract a summary: first 500 chars of content + action item count\n const summaryContent =\n minutes.content.length > 500\n ? minutes.content.slice(0, 500) + '...'\n : minutes.content;\n result = {\n id: minutes.id,\n meetingId: minutes.meetingId,\n summary: summaryContent,\n actionItemCount: minutes.actionItems.length,\n createdAt: minutes.createdAt,\n };\n break;\n }\n\n case 'tasks_only':\n result = {\n meetingId: minutes.meetingId,\n actionItems: minutes.actionItems,\n totalTasks: minutes.actionItems.length,\n };\n break;\n }\n\n return {\n content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],\n };\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n return {\n content: [\n { type: 'text', text: JSON.stringify({ error: message }, null, 2) },\n ],\n isError: true,\n };\n }\n}\n","import { z } from 'zod';\nimport { Compactor } from '../meeting/compactor.js';\n\nexport const compactMinutesSchema = {\n meetingId: z.string().describe('Meeting ID'),\n additionalInstructions: z\n .string()\n .optional()\n .describe('Additional instructions for compaction'),\n};\n\nexport async function compactMinutesHandler({\n meetingId,\n additionalInstructions,\n}: {\n meetingId: string;\n additionalInstructions?: string;\n}): Promise<{ content: { type: 'text'; text: string }[]; isError?: boolean }> {\n try {\n const compactor = new Compactor();\n const tasks = await compactor.compactMinutes(\n meetingId,\n additionalInstructions,\n );\n\n const result = {\n meetingId,\n tasksGenerated: tasks.length,\n tasks,\n };\n\n return {\n content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],\n };\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n return {\n content: [\n { type: 'text', text: JSON.stringify({ error: message }, null, 2) },\n ],\n isError: true,\n };\n }\n}\n","/**\n * Compacts meeting minutes into a structured task list per department.\n *\n * Assigns departments and priorities based on keyword analysis.\n */\n\nimport { v4 as uuidv4 } from 'uuid';\nimport { getMinutesByMeeting, createMinutes } from '../storage/index.js';\nimport { getDb } from '../storage/db.js';\nimport type { ActionItem, Department, MinutesRecord } from '../types/index.js';\nimport { logger } from '../utils/logger.js';\n\n// ---------------------------------------------------------------------------\n// Keyword → department mapping\n// ---------------------------------------------------------------------------\n\nconst DEPARTMENT_KEYWORDS: Record<Department, string[]> = {\n architecture: [\n 'schema', 'design', 'architecture', 'blueprint', 'dependency',\n 'api design', 'system design', '아키텍처', '설계',\n ],\n engineering: [\n 'implement', 'code', 'develop', 'build', 'refactor', 'fix',\n 'feature', 'module', '구현', '개발', '코드',\n ],\n qa: [\n 'test', 'quality', 'coverage', 'security', 'audit', 'performance',\n 'regression', 'validation', '테스트', '검증', '품질',\n ],\n product: [\n 'requirement', 'user story', 'acceptance criteria', 'stakeholder',\n 'priority', 'roadmap', 'scope', '요구사항', '사용자',\n ],\n research: [\n 'research', 'explore', 'investigate', 'benchmark', 'compare',\n 'evaluate', 'poc', 'prototype', '조사', '탐색',\n ],\n};\n\n// ---------------------------------------------------------------------------\n// Keyword → priority mapping\n// ---------------------------------------------------------------------------\n\nconst PRIORITY_KEYWORDS: Record<ActionItem['priority'], string[]> = {\n critical: [\n 'critical', 'urgent', 'blocker', 'blocking', 'asap', 'immediately',\n '긴급', '즉시', 'p0',\n ],\n high: [\n 'high priority', 'important', 'must', 'required', 'essential',\n '중요', '필수', 'p1',\n ],\n medium: [\n 'medium', 'should', 'moderate', '보통', 'p2',\n ],\n low: [\n 'low priority', 'nice to have', 'optional', 'consider',\n '낮음', '선택', 'p3',\n ],\n};\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction detectDepartment(text: string): Department {\n const lower = text.toLowerCase();\n let bestDept: Department = 'engineering';\n let bestScore = 0;\n\n for (const [dept, keywords] of Object.entries(DEPARTMENT_KEYWORDS) as [Department, string[]][]) {\n const score = keywords.reduce(\n (acc, kw) => acc + (lower.includes(kw.toLowerCase()) ? 1 : 0),\n 0,\n );\n if (score > bestScore) {\n bestScore = score;\n bestDept = dept;\n }\n }\n\n return bestDept;\n}\n\nfunction detectPriority(text: string): ActionItem['priority'] {\n const lower = text.toLowerCase();\n\n // Check from highest to lowest — first match wins\n for (const priority of ['critical', 'high', 'medium', 'low'] as const) {\n const keywords = PRIORITY_KEYWORDS[priority];\n if (keywords.some((kw) => lower.includes(kw.toLowerCase()))) {\n return priority;\n }\n }\n\n return 'medium';\n}\n\nconst LEADER_ROLE_FOR_DEPT: Record<Department, string> = {\n architecture: 'arch-leader',\n engineering: 'eng-leader',\n qa: 'qa-leader',\n product: 'pm-leader',\n research: 'research-leader',\n};\n\n// ---------------------------------------------------------------------------\n// Compactor\n// ---------------------------------------------------------------------------\n\nexport class Compactor {\n /**\n * Compact minutes into actionable, department-assigned tasks.\n *\n * 1. Load minutes for the meeting\n * 2. Parse action items from the minutes content\n * 3. Assign each to a department based on keywords\n * 4. Set priorities based on keywords\n * 5. Save updated action items to minutes record\n * 6. Return the structured task list\n */\n async compactMinutes(\n meetingId: string,\n additionalInstructions?: string,\n ): Promise<ActionItem[]> {\n logger.info('Compacting minutes', { meetingId });\n\n // 1. Load existing minutes\n const minutes = getMinutesByMeeting(meetingId);\n if (!minutes) {\n throw new Error(`No minutes found for meeting: ${meetingId}`);\n }\n\n // 2–4. Refine existing action items with department + priority detection\n const refinedItems: ActionItem[] = minutes.actionItems.map((item) => {\n const fullText = `${item.title} ${item.description} ${additionalInstructions ?? ''}`;\n const department = detectDepartment(fullText);\n const priority = detectPriority(fullText);\n\n return {\n ...item,\n assignedDepartment: department,\n assignedRole: LEADER_ROLE_FOR_DEPT[department],\n priority,\n };\n });\n\n // If there are no existing action items, try to extract from minutes content\n if (refinedItems.length === 0) {\n const extracted = this.extractFromContent(minutes.content);\n refinedItems.push(...extracted);\n }\n\n // 5. Update the minutes record in the DB\n const db = getDb();\n db.prepare('UPDATE minutes SET action_items = ? WHERE id = ?').run(\n JSON.stringify(refinedItems),\n minutes.id,\n );\n\n logger.info('Minutes compacted', {\n meetingId,\n actionItemCount: refinedItems.length,\n } as Record<string, unknown>);\n\n // 6. Return the structured task list\n return refinedItems;\n }\n\n // -------------------------------------------------------------------------\n // Fallback extraction from raw minutes content\n // -------------------------------------------------------------------------\n\n private extractFromContent(content: string): ActionItem[] {\n const items: ActionItem[] = [];\n const lines = content.split('\\n');\n\n for (const line of lines) {\n const trimmed = line.trim();\n // Look for lines that start with \"- \" or numbered items under action sections\n if (\n trimmed.startsWith('- ') &&\n trimmed.length > 5 &&\n trimmed !== '- None' &&\n trimmed !== '- None recorded' &&\n trimmed !== '- No action items identified' &&\n trimmed !== '- No action items recorded'\n ) {\n const text = trimmed.slice(2);\n const department = detectDepartment(text);\n const priority = detectPriority(text);\n\n items.push({\n id: uuidv4(),\n title: text.slice(0, 80),\n description: text,\n assignedDepartment: department,\n assignedRole: LEADER_ROLE_FOR_DEPT[department],\n priority,\n dependencies: [],\n acceptanceCriteria: [],\n });\n }\n }\n\n return items;\n }\n}\n","import { z } from 'zod';\nimport { getTasksFromMinutes } from '../storage/index.js';\nimport { WorkerManager } from '../orchestrator/worker-manager.js';\nimport type { TaskAssignment } from '../types/index.js';\n\nexport const executeTasksSchema = {\n meetingId: z.string().describe('Meeting ID'),\n taskIds: z\n .array(z.string())\n .optional()\n .describe('Specific tasks to execute, or all'),\n};\n\nexport async function executeTasksHandler({\n meetingId,\n taskIds,\n}: {\n meetingId: string;\n taskIds?: string[];\n}): Promise<{ content: { type: 'text'; text: string }[]; isError?: boolean }> {\n try {\n const allTasks = getTasksFromMinutes(meetingId);\n\n if (allTasks.length === 0) {\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(\n {\n error: `No tasks found for meeting: ${meetingId}. Run compact-minutes first.`,\n },\n null,\n 2,\n ),\n },\n ],\n isError: true,\n };\n }\n\n // Filter tasks if specific IDs provided\n const tasksToExecute = taskIds\n ? allTasks.filter((t) => taskIds.includes(t.id))\n : allTasks;\n\n if (tasksToExecute.length === 0) {\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(\n { error: 'No matching tasks found for the provided task IDs.' },\n null,\n 2,\n ),\n },\n ],\n isError: true,\n };\n }\n\n // Group tasks by department\n const tasksByDepartment = new Map<string, typeof tasksToExecute>();\n for (const task of tasksToExecute) {\n const dept = task.assignedDepartment;\n if (!tasksByDepartment.has(dept)) {\n tasksByDepartment.set(dept, []);\n }\n tasksByDepartment.get(dept)!.push(task);\n }\n\n const workerManager = new WorkerManager();\n const executionResults: Array<{\n department: string;\n taskCount: number;\n workers: Array<{\n id: string;\n status: string;\n taskDescription: string;\n outputResult: string | null;\n errorMessage: string | null;\n }>;\n }> = [];\n\n // Execute tasks per department\n for (const [department, tasks] of tasksByDepartment) {\n const assignments: TaskAssignment[] = tasks.map((task) => ({\n workerId: task.id,\n description: `${task.title}: ${task.description}`,\n inputPaths: [],\n outputPath: '',\n dependencies: task.dependencies,\n status: 'pending' as const,\n result: null,\n }));\n\n // Use a synthetic leader ID based on the department\n const leaderId = `${department}-leader-${meetingId}`;\n const workers = await workerManager.spawnWorkers(\n leaderId,\n meetingId,\n assignments,\n );\n\n const completedWorkers = await workerManager.executeWorkers(workers);\n\n executionResults.push({\n department,\n taskCount: tasks.length,\n workers: completedWorkers.map((w) => ({\n id: w.id,\n status: w.status,\n taskDescription: w.taskDescription,\n outputResult: w.outputResult,\n errorMessage: w.errorMessage,\n })),\n });\n }\n\n const totalWorkers = executionResults.reduce(\n (acc, r) => acc + r.workers.length,\n 0,\n );\n const completedCount = executionResults.reduce(\n (acc, r) =>\n acc + r.workers.filter((w) => w.status === 'completed').length,\n 0,\n );\n const failedCount = executionResults.reduce(\n (acc, r) => acc + r.workers.filter((w) => w.status === 'failed').length,\n 0,\n );\n\n const result = {\n meetingId,\n summary: {\n totalTasks: tasksToExecute.length,\n totalWorkers,\n completed: completedCount,\n failed: failedCount,\n },\n departments: executionResults,\n };\n\n return {\n content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],\n };\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n return {\n content: [\n { type: 'text', text: JSON.stringify({ error: message }, null, 2) },\n ],\n isError: true,\n };\n }\n}\n","import { v4 as uuidv4 } from 'uuid';\nimport type { WorkerRecord, TaskAssignment, TaskType, Department } from '../types/index.js';\nimport {\n createWorker,\n updateWorker,\n listWorkersByLeader,\n} from '../storage/index.js';\nimport { createAgentConfig } from '../agents/agent-factory.js';\nimport { invokeClaude, buildInvokeOptions } from '../agents/claude-invoker.js';\nimport { getLeaderSystemPrompt } from '../agents/leader-prompts.js';\nimport { buildWorkerPrompt } from '../agents/worker-prompts.js';\nimport { eventBus } from './event-bus.js';\nimport { logger } from '../utils/logger.js';\n\n// ---------------------------------------------------------------------------\n// Worker execution — uses Claude CLI or falls back to mock\n// ---------------------------------------------------------------------------\n\n/**\n * Execute a worker by invoking Claude CLI as a subprocess.\n *\n * When COLESLAW_MOCK=1 is set or the `claude` CLI is not available, the\n * underlying `invokeClaude` function automatically falls back to mock responses.\n */\nasync function executeWorkerAgent(worker: WorkerRecord): Promise<string> {\n // Infer the department from the task type or default to engineering\n const department: Department = inferDepartment(worker);\n\n // Infer a worker role from the task type\n const workerRole = inferWorkerRole(worker);\n\n const agentConfig = createAgentConfig({\n tier: 'worker',\n role: workerRole,\n department,\n task: worker.taskDescription,\n context: worker.inputContext ?? undefined,\n });\n\n const systemPrompt = buildWorkerPrompt({\n workerType: workerRole as import('../types/index.js').WorkerType,\n department,\n task: worker.taskDescription,\n context: worker.inputContext ?? undefined,\n });\n\n const prompt =\n `Execute the following task:\\n\\n` +\n `Task: ${worker.taskDescription}\\n` +\n (worker.inputContext ? `\\nContext: ${worker.inputContext}\\n` : '') +\n `\\nProvide a clear, structured result.`;\n\n const invokeOpts = buildInvokeOptions(agentConfig, prompt, systemPrompt);\n\n // Workers get a 5-minute timeout\n invokeOpts.timeoutMs = 300_000;\n\n const result = await invokeClaude(invokeOpts);\n\n if (!result.success) {\n throw new Error(result.error ?? 'Worker agent invocation failed');\n }\n\n return result.output;\n}\n\n/**\n * Infer the department a worker belongs to based on its task type.\n */\nfunction inferDepartment(worker: WorkerRecord): Department {\n switch (worker.taskType) {\n case 'research':\n return 'research';\n case 'testing':\n return 'qa';\n case 'analysis':\n return 'architecture';\n case 'implementation':\n default:\n return 'engineering';\n }\n}\n\n/**\n * Infer a specific worker role from the task description and type.\n */\nfunction inferWorkerRole(worker: WorkerRecord): string {\n const desc = worker.taskDescription.toLowerCase();\n\n // Architecture roles\n if (desc.includes('schema') || desc.includes('data model')) return 'schema-designer';\n if (desc.includes('api') || desc.includes('endpoint')) return 'api-designer';\n if (desc.includes('dependency') || desc.includes('coupling')) return 'dependency-analyzer';\n\n // QA roles\n if (desc.includes('test')) return 'test-writer';\n if (desc.includes('security') || desc.includes('audit')) return 'security-auditor';\n if (desc.includes('performance') || desc.includes('benchmark')) return 'perf-tester';\n\n // Research roles\n if (desc.includes('research') || desc.includes('explore') || desc.includes('investigate')) return 'code-explorer';\n if (desc.includes('document') || desc.includes('search')) return 'doc-searcher';\n\n // Engineering roles\n if (desc.includes('fix') || desc.includes('bug')) return 'bug-fixer';\n if (desc.includes('refactor')) return 'refactorer';\n\n // Default to feature-dev for implementation tasks\n return 'feature-dev';\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction inferTaskType(description: string): TaskType {\n const lower = description.toLowerCase();\n if (lower.includes('research') || lower.includes('explore') || lower.includes('search')) {\n return 'research';\n }\n if (lower.includes('test') || lower.includes('audit') || lower.includes('benchmark')) {\n return 'testing';\n }\n if (lower.includes('analys') || lower.includes('design') || lower.includes('schema')) {\n return 'analysis';\n }\n return 'implementation';\n}\n\n// ---------------------------------------------------------------------------\n// WorkerManager\n// ---------------------------------------------------------------------------\n\nexport class WorkerManager {\n // ---- spawn workers ------------------------------------------------------\n\n /**\n * Spawn a batch of workers on behalf of a leader.\n *\n * Each task assignment is persisted to SQLite and an `agent_spawned` event is\n * emitted. The returned records are in `pending` status.\n */\n async spawnWorkers(\n leaderId: string,\n meetingId: string,\n tasks: TaskAssignment[],\n ): Promise<WorkerRecord[]> {\n const workers: WorkerRecord[] = [];\n\n for (const task of tasks) {\n const worker = createWorker({\n leaderId,\n meetingId,\n taskDescription: task.description,\n taskType: inferTaskType(task.description),\n inputContext: task.inputPaths.length > 0 ? task.inputPaths.join(', ') : null,\n outputResult: null,\n errorMessage: null,\n dependencies: task.dependencies,\n });\n\n workers.push(worker);\n\n logger.info(`Spawned worker for leader ${leaderId}`, {\n agentId: worker.id,\n meetingId,\n department: 'worker',\n });\n\n eventBus.emitAgentEvent({\n kind: 'agent_spawned',\n agentId: worker.id,\n agentType: 'worker',\n parentId: leaderId,\n label: task.description.slice(0, 60),\n department: 'engineering', // Workers inherit; refined later if needed\n });\n }\n\n return workers;\n }\n\n // ---- execute workers ----------------------------------------------------\n\n /**\n * Execute a list of workers, respecting dependency ordering.\n *\n * - Workers with no unresolved dependencies run in parallel.\n * - Workers whose dependencies are all completed run next.\n * - Continues until all workers are done or a dependency cycle is detected.\n */\n async executeWorkers(workers: WorkerRecord[]): Promise<WorkerRecord[]> {\n const completed = new Set<string>();\n const results: WorkerRecord[] = [];\n const pending = new Map(workers.map((w) => [w.id, w]));\n\n while (pending.size > 0) {\n // Find workers whose dependencies are all satisfied\n const ready: WorkerRecord[] = [];\n for (const worker of pending.values()) {\n const depsReady = worker.dependencies.every((dep) => completed.has(dep));\n if (depsReady) {\n ready.push(worker);\n }\n }\n\n if (ready.length === 0) {\n // All remaining workers have unsatisfied deps — break to avoid infinite loop\n logger.warn('Dependency cycle or unsatisfiable deps detected; failing remaining workers');\n for (const worker of pending.values()) {\n const failed = updateWorker(worker.id, {\n status: 'failed',\n errorMessage: 'Unresolvable dependency',\n completedAt: Date.now(),\n });\n results.push(failed ?? worker);\n\n eventBus.emitAgentEvent({\n kind: 'task_completed',\n agentId: worker.id,\n result: 'failure',\n });\n }\n break;\n }\n\n // Execute ready batch in parallel\n const batchResults = await Promise.allSettled(\n ready.map(async (worker) => {\n // Mark running\n updateWorker(worker.id, { status: 'running' });\n eventBus.emitAgentEvent({\n kind: 'state_changed',\n agentId: worker.id,\n from: 'idle',\n to: 'working',\n });\n\n try {\n const output = await executeWorkerAgent(worker);\n const updated = updateWorker(worker.id, {\n status: 'completed',\n outputResult: output,\n completedAt: Date.now(),\n costUsd: 0.01, // Approximate cost; real cost tracked by CLI\n });\n\n eventBus.emitAgentEvent({\n kind: 'task_completed',\n agentId: worker.id,\n result: 'success',\n });\n\n return updated ?? worker;\n } catch (err) {\n const errorMsg = err instanceof Error ? err.message : String(err);\n const updated = updateWorker(worker.id, {\n status: 'failed',\n errorMessage: errorMsg,\n completedAt: Date.now(),\n });\n\n eventBus.emitAgentEvent({\n kind: 'task_completed',\n agentId: worker.id,\n result: 'failure',\n });\n\n return updated ?? worker;\n }\n }),\n );\n\n for (let i = 0; i < ready.length; i++) {\n const worker = ready[i];\n pending.delete(worker.id);\n completed.add(worker.id);\n\n const settlement = batchResults[i];\n if (settlement.status === 'fulfilled') {\n results.push(settlement.value);\n } else {\n results.push(worker);\n }\n }\n }\n\n return results;\n }\n\n // ---- status query -------------------------------------------------------\n\n /**\n * Get the current status of all workers under a given leader.\n */\n getWorkerStatus(leaderId: string): WorkerRecord[] {\n return listWorkersByLeader(leaderId);\n }\n}\n","import { getAgentTree } from '../storage/index.js';\n\nexport async function getAgentTreeHandler(): Promise<{\n content: { type: 'text'; text: string }[];\n isError?: boolean;\n}> {\n try {\n const tree = getAgentTree('orchestrator-root');\n\n const result = {\n root: tree,\n hasAgents: tree !== null,\n };\n\n return {\n content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],\n };\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n return {\n content: [\n { type: 'text', text: JSON.stringify({ error: message }, null, 2) },\n ],\n isError: true,\n };\n }\n}\n","import { z } from 'zod';\nimport { getMention, updateMention } from '../storage/index.js';\nimport { eventBus } from '../orchestrator/event-bus.js';\n\nexport const respondToMentionSchema = {\n mentionId: z.string().describe('ID of the mention to respond to'),\n decision: z.string().describe('The decision made by the user'),\n reasoning: z.string().optional().describe('Optional reasoning for the decision'),\n};\n\nexport async function respondToMentionHandler({\n mentionId,\n decision,\n reasoning,\n}: {\n mentionId: string;\n decision: string;\n reasoning?: string;\n}): Promise<{ content: { type: 'text'; text: string }[]; isError?: boolean }> {\n try {\n const mention = getMention(mentionId);\n\n if (!mention) {\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(\n { error: `Mention not found: ${mentionId}` },\n null,\n 2,\n ),\n },\n ],\n isError: true,\n };\n }\n\n if (mention.status === 'resolved') {\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(\n { error: `Mention already resolved: ${mentionId}` },\n null,\n 2,\n ),\n },\n ],\n isError: true,\n };\n }\n\n const resolved = updateMention(mentionId, {\n status: 'resolved',\n userDecision: decision,\n userReasoning: reasoning ?? null,\n resolvedAt: Date.now(),\n });\n\n eventBus.emitAgentEvent({\n kind: 'mention_resolved',\n mentionId,\n decision,\n });\n\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(\n { success: true, mention: resolved },\n null,\n 2,\n ),\n },\n ],\n };\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n return {\n content: [\n { type: 'text', text: JSON.stringify({ error: message }, null, 2) },\n ],\n isError: true,\n };\n }\n}\n","import { z } from 'zod';\nimport {\n listPendingMentions,\n listMentionsByMeeting,\n} from '../storage/index.js';\nimport type { MentionRecord } from '../types/index.js';\n\nexport const getMentionsSchema = {\n status: z\n .enum(['pending', 'resolved', 'all'])\n .default('pending')\n .optional()\n .describe('Filter mentions by status'),\n meetingId: z\n .string()\n .optional()\n .describe('Filter mentions by meeting ID'),\n};\n\nexport async function getMentionsHandler({\n status,\n meetingId,\n}: {\n status?: 'pending' | 'resolved' | 'all';\n meetingId?: string;\n}): Promise<{ content: { type: 'text'; text: string }[]; isError?: boolean }> {\n try {\n const effectiveStatus = status ?? 'pending';\n let mentions: MentionRecord[];\n\n if (meetingId) {\n // Get all mentions for this meeting, then filter by status\n const allForMeeting = listMentionsByMeeting(meetingId);\n if (effectiveStatus === 'all') {\n mentions = allForMeeting;\n } else {\n mentions = allForMeeting.filter((m) => m.status === effectiveStatus);\n }\n } else if (effectiveStatus === 'pending') {\n mentions = listPendingMentions();\n } else if (effectiveStatus === 'resolved') {\n // listPendingMentions only returns pending; for resolved we need to\n // get all and filter. Since there is no dedicated storage function for\n // resolved mentions, we use listMentionsByMeeting with no meetingId —\n // but that requires a meetingId. Instead we get pending and note the\n // limitation, or we query directly.\n // For a clean approach, list all meetings' mentions by getting pending\n // and noting this is a filtered view.\n // Actually, we can use the DB directly through the existing functions.\n // The simplest correct approach: get all pending and return empty since\n // we want resolved. But that's wrong. Let's just get all mentions.\n // Since there's no listAllMentions, we'll import getDb and query directly.\n const { getDb } = await import('../storage/db.js');\n const db = getDb();\n interface MentionRow {\n id: string;\n meeting_id: string;\n agenda_item: string | null;\n summary: string;\n options: string;\n urgency: string;\n status: string;\n user_decision: string | null;\n user_reasoning: string | null;\n created_at: number;\n resolved_at: number | null;\n }\n const rows = db\n .prepare(\"SELECT * FROM mentions WHERE status = 'resolved' ORDER BY created_at ASC\")\n .all() as MentionRow[];\n mentions = rows.map((row) => ({\n id: row.id,\n meetingId: row.meeting_id,\n agendaItem: row.agenda_item,\n summary: row.summary,\n options: JSON.parse(row.options),\n urgency: row.urgency as MentionRecord['urgency'],\n status: row.status as MentionRecord['status'],\n userDecision: row.user_decision,\n userReasoning: row.user_reasoning,\n createdAt: row.created_at,\n resolvedAt: row.resolved_at,\n }));\n } else {\n // 'all'\n const { getDb } = await import('../storage/db.js');\n const db = getDb();\n interface MentionRow {\n id: string;\n meeting_id: string;\n agenda_item: string | null;\n summary: string;\n options: string;\n urgency: string;\n status: string;\n user_decision: string | null;\n user_reasoning: string | null;\n created_at: number;\n resolved_at: number | null;\n }\n const rows = db\n .prepare('SELECT * FROM mentions ORDER BY created_at ASC')\n .all() as MentionRow[];\n mentions = rows.map((row) => ({\n id: row.id,\n meetingId: row.meeting_id,\n agendaItem: row.agenda_item,\n summary: row.summary,\n options: JSON.parse(row.options),\n urgency: row.urgency as MentionRecord['urgency'],\n status: row.status as MentionRecord['status'],\n userDecision: row.user_decision,\n userReasoning: row.user_reasoning,\n createdAt: row.created_at,\n resolvedAt: row.resolved_at,\n }));\n }\n\n const result = {\n count: mentions.length,\n status: effectiveStatus,\n ...(meetingId ? { meetingId } : {}),\n mentions,\n };\n\n return {\n content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],\n };\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n return {\n content: [\n { type: 'text', text: JSON.stringify({ error: message }, null, 2) },\n ],\n isError: true,\n };\n }\n}\n","import { z } from 'zod';\nimport {\n getMeeting,\n updateMeeting,\n listAgentsByMeeting,\n updateAgent,\n listWorkersByLeader,\n updateWorker,\n} from '../storage/index.js';\nimport { eventBus } from '../orchestrator/event-bus.js';\n\nexport const cancelMeetingSchema = {\n meetingId: z.string().describe('ID of the meeting to cancel'),\n reason: z.string().optional().describe('Reason for cancellation'),\n};\n\nexport async function cancelMeetingHandler({\n meetingId,\n reason,\n}: {\n meetingId: string;\n reason?: string;\n}): Promise<{ content: { type: 'text'; text: string }[]; isError?: boolean }> {\n try {\n const meeting = getMeeting(meetingId);\n\n if (!meeting) {\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(\n { error: `Meeting not found: ${meetingId}` },\n null,\n 2,\n ),\n },\n ],\n isError: true,\n };\n }\n\n if (meeting.status === 'completed' || meeting.status === 'cancelled') {\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(\n {\n error: `Meeting cannot be cancelled: current status is '${meeting.status}'`,\n },\n null,\n 2,\n ),\n },\n ],\n isError: true,\n };\n }\n\n // Update meeting status to cancelled\n updateMeeting(meetingId, { status: 'cancelled', completedAt: Date.now() });\n\n // Find all agents for this meeting and mark them as completed\n const agents = listAgentsByMeeting(meetingId);\n let agentsCancelled = 0;\n let workersFailed = 0;\n\n for (const agent of agents) {\n if (agent.status !== 'completed' && agent.status !== 'failed') {\n updateAgent(agent.id, { status: 'completed', completedAt: Date.now() });\n agentsCancelled++;\n\n eventBus.emitAgentEvent({\n kind: 'state_changed',\n agentId: agent.id,\n from: agent.status,\n to: 'completed',\n });\n }\n\n // Find all workers for this agent (leader) and mark them as failed\n const workers = listWorkersByLeader(agent.id);\n for (const worker of workers) {\n if (worker.status !== 'completed' && worker.status !== 'failed') {\n updateWorker(worker.id, {\n status: 'failed',\n errorMessage: reason ?? 'Meeting cancelled',\n completedAt: Date.now(),\n });\n workersFailed++;\n\n eventBus.emitAgentEvent({\n kind: 'task_completed',\n agentId: worker.id,\n result: 'failure',\n });\n }\n }\n }\n\n const result = {\n success: true,\n meetingId,\n previousStatus: meeting.status,\n reason: reason ?? 'No reason provided',\n agentsCancelled,\n workersFailed,\n };\n\n return {\n content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],\n };\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n return {\n content: [\n { type: 'text', text: JSON.stringify({ error: message }, null, 2) },\n ],\n isError: true,\n };\n }\n}\n","import { z } from 'zod';\nimport { listMeetings } from '../storage/index.js';\nimport type { MeetingStatus } from '../types/index.js';\n\nexport const listMeetingsSchema = {\n status: z\n .enum(['pending', 'running', 'completed', 'cancelled', 'failed', 'all'])\n .default('all')\n .optional()\n .describe('Filter meetings by status'),\n limit: z\n .number()\n .default(20)\n .optional()\n .describe('Maximum number of meetings to return'),\n};\n\n// Map the user-facing \"running\" status to the internal statuses that represent\n// an active/running meeting.\nconst RUNNING_STATUSES: MeetingStatus[] = [\n 'convening',\n 'opening',\n 'discussion',\n 'synthesis',\n 'minutes-generation',\n 'executing',\n 'aggregation',\n 'waiting-for-user',\n];\n\nexport async function listMeetingsHandler({\n status,\n limit,\n}: {\n status?: 'pending' | 'running' | 'completed' | 'cancelled' | 'failed' | 'all';\n limit?: number;\n}): Promise<{ content: { type: 'text'; text: string }[]; isError?: boolean }> {\n try {\n const effectiveStatus = status ?? 'all';\n const effectiveLimit = limit ?? 20;\n\n let meetings;\n\n if (effectiveStatus === 'all') {\n meetings = listMeetings();\n } else if (effectiveStatus === 'running') {\n // \"running\" maps to multiple internal statuses\n const all = listMeetings();\n meetings = all.filter((m) => RUNNING_STATUSES.includes(m.status));\n } else {\n meetings = listMeetings(effectiveStatus as MeetingStatus);\n }\n\n // Apply limit\n const limited = meetings.slice(0, effectiveLimit);\n\n const result = {\n total: meetings.length,\n returned: limited.length,\n status: effectiveStatus,\n meetings: limited.map((m) => ({\n id: m.id,\n topic: m.topic,\n status: m.status,\n phase: m.phase,\n participantCount: m.participantIds.length,\n startedAt: m.startedAt,\n })),\n };\n\n return {\n content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],\n };\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n return {\n content: [\n { type: 'text', text: JSON.stringify({ error: message }, null, 2) },\n ],\n isError: true,\n };\n }\n}\n","import { z } from 'zod';\nimport {\n getMeeting,\n getMinutesByMeeting,\n listAgentsByMeeting,\n listWorkersByLeader,\n} from '../storage/index.js';\n\nexport const getTaskReportSchema = {\n meetingId: z.string().describe('ID of the meeting to generate a report for'),\n};\n\nexport async function getTaskReportHandler({\n meetingId,\n}: {\n meetingId: string;\n}): Promise<{ content: { type: 'text'; text: string }[]; isError?: boolean }> {\n try {\n const meeting = getMeeting(meetingId);\n if (!meeting) {\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(\n { error: `Meeting not found: ${meetingId}` },\n null,\n 2,\n ),\n },\n ],\n isError: true,\n };\n }\n\n const minutes = getMinutesByMeeting(meetingId);\n const agents = listAgentsByMeeting(meetingId);\n\n // Collect all workers grouped by leader/department\n const departmentBreakdowns: Array<{\n department: string;\n leaderId: string;\n leaderRole: string;\n workers: Array<{\n id: string;\n taskDescription: string;\n status: string;\n costUsd: number;\n errorMessage: string | null;\n }>;\n completed: number;\n failed: number;\n pending: number;\n totalCost: number;\n }> = [];\n\n let totalCompleted = 0;\n let totalFailed = 0;\n let totalPending = 0;\n let totalCost = 0;\n\n for (const agent of agents) {\n const workers = listWorkersByLeader(agent.id);\n\n const completed = workers.filter((w) => w.status === 'completed').length;\n const failed = workers.filter((w) => w.status === 'failed').length;\n const pending = workers.filter(\n (w) => w.status === 'pending' || w.status === 'running',\n ).length;\n const deptCost = workers.reduce((acc, w) => acc + w.costUsd, 0);\n\n totalCompleted += completed;\n totalFailed += failed;\n totalPending += pending;\n totalCost += deptCost;\n\n if (workers.length > 0) {\n departmentBreakdowns.push({\n department: agent.department,\n leaderId: agent.id,\n leaderRole: agent.role,\n workers: workers.map((w) => ({\n id: w.id,\n taskDescription: w.taskDescription,\n status: w.status,\n costUsd: w.costUsd,\n errorMessage: w.errorMessage,\n })),\n completed,\n failed,\n pending,\n totalCost: deptCost,\n });\n }\n }\n\n const result = {\n meetingId,\n topic: meeting.topic,\n status: meeting.status,\n actionItemCount: minutes?.actionItems.length ?? 0,\n summary: {\n totalWorkers: totalCompleted + totalFailed + totalPending,\n completed: totalCompleted,\n failed: totalFailed,\n pending: totalPending,\n totalCost,\n },\n departments: departmentBreakdowns,\n };\n\n return {\n content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],\n };\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n return {\n content: [\n { type: 'text', text: JSON.stringify({ error: message }, null, 2) },\n ],\n isError: true,\n };\n }\n}\n","import { z } from 'zod';\nimport { ExtensionManager } from '../extension/extension-manager.js';\nimport type { CapabilityType } from '../extension/capability-registry.js';\nimport type { GenerateRequest } from '../extension/generator.js';\n\nexport const createCapabilitySchema = {\n type: z\n .enum(['hook', 'skill', 'command', 'asset', 'loop'])\n .describe('Type of capability to create'),\n name: z.string().describe('Name for the new capability'),\n description: z.string().describe('What the capability does'),\n trigger: z.string().describe('When the capability should be triggered'),\n userRequest: z\n .string()\n .optional()\n .describe('Original user request that triggered creation'),\n};\n\nexport async function createCapabilityHandler({\n type,\n name,\n description,\n trigger,\n userRequest,\n}: {\n type: 'hook' | 'skill' | 'command' | 'asset' | 'loop';\n name: string;\n description: string;\n trigger: string;\n userRequest?: string;\n}): Promise<{ content: { type: 'text'; text: string }[]; isError?: boolean }> {\n try {\n const manager = new ExtensionManager();\n await manager.init();\n\n const request: GenerateRequest = {\n type: type as CapabilityType,\n name,\n description,\n trigger,\n userRequest: userRequest ?? description,\n };\n\n const result = await manager.createCapability(request);\n\n const output = {\n status: 'created',\n capability: {\n type: result.capability.type,\n name: result.capability.name,\n description: result.capability.description,\n trigger: result.capability.trigger,\n isBuiltIn: result.capability.isBuiltIn,\n },\n filePath: result.filePath,\n summary: result.summary,\n };\n\n return {\n content: [{ type: 'text', text: JSON.stringify(output, null, 2) }],\n };\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n return {\n content: [\n { type: 'text', text: JSON.stringify({ error: message }, null, 2) },\n ],\n isError: true,\n };\n }\n}\n","/**\n * capability-registry.ts — Tracks all registered capabilities (built-in + custom).\n *\n * The registry is persisted to ~/.open-coleslaw/registry.json.\n * Built-in capabilities (the 6 hooks + 6 skills that ship with the project) are\n * hardcoded; custom capabilities are added/removed dynamically at runtime.\n */\n\nimport { readFileSync, writeFileSync, existsSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { getConfig } from '../utils/config.js';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport type CapabilityType = 'hook' | 'skill' | 'command' | 'asset' | 'loop';\n\nexport interface Capability {\n type: CapabilityType;\n name: string;\n description: string;\n trigger: string;\n createdAt: number;\n isBuiltIn: boolean;\n filePath: string;\n}\n\n// ---------------------------------------------------------------------------\n// Built-in capability definitions\n// ---------------------------------------------------------------------------\n\nconst BUILT_IN_HOOKS: Omit<Capability, 'createdAt'>[] = [\n {\n type: 'hook',\n name: 'pre-read',\n description: 'Loads rules + plugin guide + CLAUDE.md/README before execution',\n trigger: 'Before every execution',\n isBuiltIn: true,\n filePath: 'src/hooks/pre-read.ts',\n },\n {\n type: 'hook',\n name: 'auto-route',\n description: 'Analyzes user prompts and auto-routes to appropriate skill/agent',\n trigger: 'On every user prompt',\n isBuiltIn: true,\n filePath: 'src/hooks/auto-route.ts',\n },\n {\n type: 'hook',\n name: 'auto-commit',\n description: 'Creates conventional commits after task completion',\n trigger: 'After task completion when git is connected',\n isBuiltIn: true,\n filePath: 'src/hooks/auto-commit.ts',\n },\n {\n type: 'hook',\n name: 'doc-update',\n description: 'Updates CLAUDE.md/README.md after process completion',\n trigger: 'After process completion',\n isBuiltIn: true,\n filePath: 'src/hooks/doc-update.ts',\n },\n {\n type: 'hook',\n name: 'flow-verify',\n description: 'Verifies PRD user flows after development',\n trigger: 'After development phase completes',\n isBuiltIn: true,\n filePath: 'src/hooks/flow-verify.ts',\n },\n {\n type: 'hook',\n name: 'mvp-cycle',\n description: 'Triggers re-meeting on verification failure',\n trigger: 'When flow-verify reports failure',\n isBuiltIn: true,\n filePath: 'src/hooks/mvp-cycle.ts',\n },\n];\n\nconst BUILT_IN_SKILLS: Omit<Capability, 'createdAt'>[] = [\n {\n type: 'skill',\n name: 'meeting',\n description: 'Start a meeting (auto-selects leaders if topic given)',\n trigger: '/meeting [topic]',\n isBuiltIn: true,\n filePath: 'src/skills/meeting.ts',\n },\n {\n type: 'skill',\n name: 'status',\n description: 'Show current meetings, agents, and pending mentions',\n trigger: '/status',\n isBuiltIn: true,\n filePath: 'src/skills/status.ts',\n },\n {\n type: 'skill',\n name: 'dashboard',\n description: 'Open web dashboard at http://localhost:35143',\n trigger: '/dashboard',\n isBuiltIn: true,\n filePath: 'src/skills/dashboard.ts',\n },\n {\n type: 'skill',\n name: 'mention',\n description: 'View and respond to pending @mentions',\n trigger: '/mention',\n isBuiltIn: true,\n filePath: 'src/skills/mention.ts',\n },\n {\n type: 'skill',\n name: 'agents',\n description: 'Show full agent hierarchy tree',\n trigger: '/agents',\n isBuiltIn: true,\n filePath: 'src/skills/agents.ts',\n },\n {\n type: 'skill',\n name: 'minutes',\n description: 'View meeting minutes',\n trigger: '/minutes [meetingId]',\n isBuiltIn: true,\n filePath: 'src/skills/minutes.ts',\n },\n];\n\n// ---------------------------------------------------------------------------\n// Registry class\n// ---------------------------------------------------------------------------\n\nexport class CapabilityRegistry {\n private capabilities: Capability[] = [];\n private registryPath: string;\n\n constructor() {\n const { DATA_DIR } = getConfig();\n this.registryPath = join(DATA_DIR, 'registry.json');\n }\n\n /**\n * Load all capabilities: built-in (hardcoded) + custom (from registry.json).\n */\n async loadAll(): Promise<Capability[]> {\n // Start with built-in capabilities (timestamp 0 — they always existed)\n const builtIns: Capability[] = [\n ...BUILT_IN_HOOKS,\n ...BUILT_IN_SKILLS,\n ].map((cap) => ({ ...cap, createdAt: 0 }));\n\n // Merge in custom capabilities from persistent storage\n const custom = this.readCustomEntries();\n this.capabilities = [...builtIns, ...custom];\n return this.capabilities;\n }\n\n /**\n * Register a new custom capability and persist.\n */\n async register(cap: Omit<Capability, 'createdAt'>): Promise<void> {\n const entry: Capability = { ...cap, createdAt: Date.now() };\n\n // Remove any existing entry with the same name to avoid duplicates\n const custom = this.readCustomEntries().filter((c) => c.name !== cap.name);\n custom.push(entry);\n this.writeCustomEntries(custom);\n\n // Refresh in-memory list\n await this.loadAll();\n }\n\n /**\n * Unregister a custom capability and persist.\n */\n async unregister(type: CapabilityType, name: string): Promise<void> {\n const custom = this.readCustomEntries().filter(\n (c) => !(c.type === type && c.name === name),\n );\n this.writeCustomEntries(custom);\n\n // Refresh in-memory list\n await this.loadAll();\n }\n\n /**\n * Find capabilities by type.\n */\n findByType(type: CapabilityType): Capability[] {\n return this.capabilities.filter((c) => c.type === type);\n }\n\n /**\n * Find a capability by name.\n */\n findByName(name: string): Capability | undefined {\n return this.capabilities.find((c) => c.name === name);\n }\n\n /**\n * Check whether a capability with the given name exists.\n */\n has(name: string): boolean {\n return this.capabilities.some((c) => c.name === name);\n }\n\n /**\n * Format all capabilities as a human-readable list suitable for plugin-guide.md.\n */\n formatForGuide(): string {\n const sections: string[] = [];\n\n const types: CapabilityType[] = ['hook', 'skill', 'command', 'asset', 'loop'];\n for (const type of types) {\n const caps = this.findByType(type);\n if (caps.length === 0) continue;\n\n const label = type.charAt(0).toUpperCase() + type.slice(1) + 's';\n const lines = caps.map((c) => {\n const tag = c.isBuiltIn ? '' : ' [custom]';\n return `- **${c.name}**${tag} — ${c.description} (trigger: ${c.trigger})`;\n });\n sections.push(`### ${label}\\n${lines.join('\\n')}`);\n }\n\n return sections.join('\\n\\n');\n }\n\n // -------------------------------------------------------------------------\n // Private helpers\n // -------------------------------------------------------------------------\n\n private readCustomEntries(): Capability[] {\n if (!existsSync(this.registryPath)) {\n return [];\n }\n try {\n const raw = readFileSync(this.registryPath, 'utf-8');\n const parsed: unknown = JSON.parse(raw);\n if (!Array.isArray(parsed)) return [];\n return parsed as Capability[];\n } catch {\n return [];\n }\n }\n\n private writeCustomEntries(entries: Capability[]): void {\n writeFileSync(this.registryPath, JSON.stringify(entries, null, 2), 'utf-8');\n }\n}\n","import { mkdirSync } from 'node:fs';\nimport { homedir } from 'node:os';\nimport { join } from 'node:path';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport interface AppConfig {\n /** Root data directory: ~/.open-coleslaw/ */\n DATA_DIR: string;\n /** SQLite database path: ~/.open-coleslaw/data.db */\n DB_PATH: string;\n /** Directory for meeting minutes files: ~/.open-coleslaw/minutes/ */\n MINUTES_DIR: string;\n /** WebSocket dashboard port */\n DASHBOARD_PORT: number;\n}\n\n// ---------------------------------------------------------------------------\n// Defaults\n// ---------------------------------------------------------------------------\n\nfunction buildConfig(): AppConfig {\n const DATA_DIR = join(homedir(), '.open-coleslaw');\n return {\n DATA_DIR,\n DB_PATH: join(DATA_DIR, 'data.db'),\n MINUTES_DIR: join(DATA_DIR, 'minutes'),\n DASHBOARD_PORT: 35143,\n };\n}\n\n// Singleton — computed once, reused thereafter.\nlet _config: AppConfig | null = null;\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Return the runtime configuration.\n *\n * Values are derived from well-known paths under `~/.open-coleslaw/`.\n * The config object is created once and cached for the lifetime of the process.\n */\nexport function getConfig(): AppConfig {\n if (!_config) {\n _config = buildConfig();\n }\n return _config;\n}\n\n/**\n * Ensure all required data directories exist (creates them recursively if missing).\n *\n * Call this once during server startup before any storage or file I/O.\n */\nexport function ensureDataDirs(): void {\n const config = getConfig();\n mkdirSync(config.DATA_DIR, { recursive: true });\n mkdirSync(config.MINUTES_DIR, { recursive: true });\n}\n","/**\n * generator.ts — Generates code for new capabilities.\n *\n * Each capability type has a template that produces a standalone file.\n * Generated files are placed in ~/.open-coleslaw/custom-{type}s/.\n */\n\nimport { mkdirSync, writeFileSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { getConfig } from '../utils/config.js';\nimport type { CapabilityType, Capability } from './capability-registry.js';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport interface GenerateRequest {\n type: CapabilityType;\n name: string;\n description: string;\n trigger: string;\n userRequest: string;\n}\n\nexport interface GenerateResult {\n filePath: string;\n code: string;\n registryEntry: Omit<Capability, 'createdAt'>;\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction sanitizeName(name: string): string {\n return name\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, '-')\n .replace(/^-+|-+$/g, '');\n}\n\nfunction header(request: GenerateRequest): string {\n const now = new Date().toISOString();\n return [\n `// Auto-generated by open-coleslaw extension system`,\n `// Name: ${request.name}`,\n `// Description: ${request.description}`,\n `// Trigger: ${request.trigger}`,\n `// Created: ${now}`,\n '',\n ].join('\\n');\n}\n\nfunction customDir(type: CapabilityType): string {\n const { DATA_DIR } = getConfig();\n const dir = join(DATA_DIR, `custom-${type}s`);\n mkdirSync(dir, { recursive: true });\n return dir;\n}\n\n// ---------------------------------------------------------------------------\n// Templates per capability type\n// ---------------------------------------------------------------------------\n\nfunction generateHook(request: GenerateRequest): string {\n return [\n header(request),\n `/**`,\n ` * Custom hook: ${request.name}`,\n ` * ${request.description}`,\n ` *`,\n ` * Trigger: ${request.trigger}`,\n ` * Original request: ${request.userRequest}`,\n ` *`,\n ` * Usage:`,\n ` * node custom-hooks/${sanitizeName(request.name)}.js`,\n ` */`,\n ``,\n `function main() {`,\n ` // Read input from stdin or environment if needed`,\n ` const input = process.env.HOOK_INPUT ?? '';`,\n ``,\n ` // TODO: Implement hook logic for \"${request.description}\"`,\n ` const result = {`,\n ` hook: '${request.name}',`,\n ` status: 'executed',`,\n ` input,`,\n ` timestamp: new Date().toISOString(),`,\n ` };`,\n ``,\n ` process.stdout.write(JSON.stringify(result));`,\n `}`,\n ``,\n `main();`,\n ``,\n ].join('\\n');\n}\n\nfunction generateSkill(request: GenerateRequest): string {\n return [\n header(request),\n `/**`,\n ` * Custom skill: ${request.name}`,\n ` * ${request.description}`,\n ` *`,\n ` * Trigger: ${request.trigger}`,\n ` * Original request: ${request.userRequest}`,\n ` */`,\n ``,\n `export function get${toPascalCase(request.name)}SkillPrompt(args) {`,\n ` const input = args?.trim() ?? '';`,\n ``,\n ` return [`,\n ` '<command-name>${request.name}</command-name>',`,\n ` '',`,\n ` '## ${request.name} Skill',`,\n ` '',`,\n ` '${request.description}',`,\n ` '',`,\n ` input ? \\`User input: \\${input}\\` : 'No input provided.',`,\n ` '',`,\n ` 'Instructions:',`,\n ` '1. Analyze the user request',`,\n ` '2. Perform the action described above',`,\n ` '3. Report the result to the user',`,\n ` ].join('\\\\n');`,\n `}`,\n ``,\n ].join('\\n');\n}\n\nfunction generateCommand(request: GenerateRequest): string {\n return [\n header(request),\n `/**`,\n ` * Custom command: ${request.name}`,\n ` * ${request.description}`,\n ` *`,\n ` * Trigger: ${request.trigger}`,\n ` * Original request: ${request.userRequest}`,\n ` *`,\n ` * Usage:`,\n ` * node custom-commands/${sanitizeName(request.name)}.js [action] [args...]`,\n ` */`,\n ``,\n `function main() {`,\n ` const args = process.argv.slice(2);`,\n ` const action = args[0] ?? 'default';`,\n ` const rest = args.slice(1);`,\n ``,\n ` const handlers = {`,\n ` default: () => ({`,\n ` command: '${request.name}',`,\n ` description: '${request.description}',`,\n ` usage: '${request.name}:action [args]',`,\n ` }),`,\n ` run: () => {`,\n ` // TODO: Implement the primary command action`,\n ` return {`,\n ` command: '${request.name}',`,\n ` action: 'run',`,\n ` args: rest,`,\n ` status: 'executed',`,\n ` timestamp: new Date().toISOString(),`,\n ` };`,\n ` },`,\n ` };`,\n ``,\n ` const handler = handlers[action] ?? handlers.default;`,\n ` const result = handler();`,\n ` process.stdout.write(JSON.stringify(result, null, 2));`,\n `}`,\n ``,\n `main();`,\n ``,\n ].join('\\n');\n}\n\nfunction generateAsset(request: GenerateRequest): string {\n // Assets can be JSON or Markdown. Default to JSON for configs, Markdown for docs.\n const isMarkdown =\n /template|guide|doc|readme|note/i.test(request.name) ||\n /template|guide|doc|readme|note/i.test(request.description);\n\n if (isMarkdown) {\n return [\n `<!-- Auto-generated by open-coleslaw extension system -->`,\n `<!-- Name: ${request.name} -->`,\n `<!-- Description: ${request.description} -->`,\n `<!-- Trigger: ${request.trigger} -->`,\n `<!-- Created: ${new Date().toISOString()} -->`,\n ``,\n `# ${request.name}`,\n ``,\n `${request.description}`,\n ``,\n `## Details`,\n ``,\n `> Original request: ${request.userRequest}`,\n ``,\n `<!-- TODO: Fill in content -->`,\n ``,\n ].join('\\n');\n }\n\n const data = {\n _meta: {\n generatedBy: 'open-coleslaw extension system',\n name: request.name,\n description: request.description,\n trigger: request.trigger,\n created: new Date().toISOString(),\n userRequest: request.userRequest,\n },\n config: {},\n };\n\n return JSON.stringify(data, null, 2) + '\\n';\n}\n\nfunction generateLoop(request: GenerateRequest): string {\n return [\n header(request),\n `/**`,\n ` * Custom loop: ${request.name}`,\n ` * ${request.description}`,\n ` *`,\n ` * Trigger: ${request.trigger}`,\n ` * Original request: ${request.userRequest}`,\n ` *`,\n ` * Usage:`,\n ` * node custom-loops/${sanitizeName(request.name)}.js`,\n ` */`,\n ``,\n `const INTERVAL_MS = 30000; // 30 seconds`,\n `const MAX_ITERATIONS = 100;`,\n ``,\n `async function check() {`,\n ` // TODO: Implement the condition check for \"${request.description}\"`,\n ` const result = {`,\n ` loop: '${request.name}',`,\n ` iteration: 0,`,\n ` timestamp: new Date().toISOString(),`,\n ` conditionMet: false,`,\n ` };`,\n ` return result;`,\n `}`,\n ``,\n `async function main() {`,\n ` let iteration = 0;`,\n ``,\n ` while (iteration < MAX_ITERATIONS) {`,\n ` iteration++;`,\n ` const result = await check();`,\n ` result.iteration = iteration;`,\n ``,\n ` process.stdout.write(JSON.stringify(result) + '\\\\n');`,\n ``,\n ` if (result.conditionMet) {`,\n ` process.stdout.write(JSON.stringify({`,\n ` loop: '${request.name}',`,\n ` status: 'completed',`,\n ` totalIterations: iteration,`,\n ` }) + '\\\\n');`,\n ` break;`,\n ` }`,\n ``,\n ` await new Promise((resolve) => setTimeout(resolve, INTERVAL_MS));`,\n ` }`,\n `}`,\n ``,\n `main().catch((err) => {`,\n ` process.stderr.write(String(err));`,\n ` process.exit(1);`,\n `});`,\n ``,\n ].join('\\n');\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction toPascalCase(str: string): string {\n return str\n .split(/[-_\\s]+/)\n .map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())\n .join('');\n}\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Generate code for a new capability.\n *\n * Returns the file path where the code was written, the code itself,\n * and the registry entry to persist.\n */\nexport function generateCapability(request: GenerateRequest): GenerateResult {\n const safeName = sanitizeName(request.name);\n\n // Determine file extension based on type\n const isAssetMarkdown =\n request.type === 'asset' &&\n (/template|guide|doc|readme|note/i.test(request.name) ||\n /template|guide|doc|readme|note/i.test(request.description));\n\n let ext: string;\n if (request.type === 'asset') {\n ext = isAssetMarkdown ? '.md' : '.json';\n } else {\n ext = '.js';\n }\n\n const dir = customDir(request.type);\n const filePath = join(dir, `${safeName}${ext}`);\n\n // Generate the code\n let code: string;\n switch (request.type) {\n case 'hook':\n code = generateHook(request);\n break;\n case 'skill':\n code = generateSkill(request);\n break;\n case 'command':\n code = generateCommand(request);\n break;\n case 'asset':\n code = generateAsset(request);\n break;\n case 'loop':\n code = generateLoop(request);\n break;\n }\n\n // Write the file\n writeFileSync(filePath, code, 'utf-8');\n\n return {\n filePath,\n code,\n registryEntry: {\n type: request.type,\n name: request.name,\n description: request.description,\n trigger: request.trigger,\n isBuiltIn: false,\n filePath,\n },\n };\n}\n","/**\n * guide-updater.ts — Updates plugin-guide.md and rules.md when capabilities change.\n *\n * Regenerates plugin-guide.md with the current set of capabilities.\n * For rules.md, only appends custom rules — never removes base rules.\n */\n\nimport { readFileSync, writeFileSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { getConfig } from '../utils/config.js';\nimport type { CapabilityRegistry } from './capability-registry.js';\n\n// ---------------------------------------------------------------------------\n// Plugin guide\n// ---------------------------------------------------------------------------\n\n/**\n * Regenerate plugin-guide.md with the current set of registered capabilities.\n *\n * The guide is written to ~/.open-coleslaw/plugin-guide.md where the pre-read\n * hook picks it up.\n */\nexport async function updatePluginGuide(\n registry: CapabilityRegistry,\n): Promise<void> {\n const { DATA_DIR } = getConfig();\n const guidePath = join(DATA_DIR, 'plugin-guide.md');\n\n const capSection = registry.formatForGuide();\n\n const guide = [\n '# Open-Coleslaw Plugin Guide',\n '',\n '## Overview',\n 'Multi-agent orchestrator for Claude Code. Hierarchical agent system:',\n 'Orchestrator (proxy) -> Part Leaders (team leads) -> Workers (executors)',\n '',\n '## Registered Capabilities',\n '',\n capSection,\n '',\n '## Agent Tiers',\n '| Tier | Model | Role |',\n '|------|-------|------|',\n '| Orchestrator | claude-opus-4-6 (1M) | Full-picture routing, delegation |',\n '| Leader | claude-sonnet-4-6 | Meetings, technical decisions |',\n '| Worker (impl) | claude-sonnet-4-6 | Code, implementation |',\n '| Worker (research) | claude-haiku-4-5 | Quick lookups |',\n '',\n '## Departments',\n '- Architecture: system design, API, schema',\n '- Engineering: implementation, code quality',\n '- QA: testing, security, performance',\n '- Product: requirements, user stories',\n '- Research: codebase exploration, docs',\n '',\n '## Meeting Minutes',\n 'Saved to: ~/.open-coleslaw/minutes/',\n 'Index: ~/.open-coleslaw/minutes/INDEX.md',\n 'Format: PRD with frontmatter metadata + tags',\n '',\n '## Extension System',\n 'Custom capabilities are stored in ~/.open-coleslaw/custom-{type}s/.',\n 'Use the `create-capability` MCP tool to add new hooks, skills, commands, assets, or loops.',\n 'Registry: ~/.open-coleslaw/registry.json',\n '',\n ].join('\\n');\n\n writeFileSync(guidePath, guide, 'utf-8');\n}\n\n// ---------------------------------------------------------------------------\n// Rules\n// ---------------------------------------------------------------------------\n\n/** Sentinel that marks the beginning of the custom-rules block. */\nconst CUSTOM_RULES_START = '## Custom Rules';\nconst CUSTOM_RULES_END = '<!-- /custom-rules -->';\n\n/**\n * Append custom rules to rules.md without removing any base rules.\n *\n * Custom rules are bracketed between a `## Custom Rules` heading and\n * a closing HTML comment so they can be cleanly replaced on subsequent calls.\n */\nexport async function updateRulesIfNeeded(\n customRules: string[],\n): Promise<void> {\n if (customRules.length === 0) return;\n\n const { DATA_DIR } = getConfig();\n const rulesPath = join(DATA_DIR, 'rules.md');\n\n let existing: string;\n try {\n existing = readFileSync(rulesPath, 'utf-8');\n } catch {\n // If no rules.md yet, start from an empty document\n existing = '';\n }\n\n // Strip any previous custom-rules block\n const startIdx = existing.indexOf(CUSTOM_RULES_START);\n const endIdx = existing.indexOf(CUSTOM_RULES_END);\n let base: string;\n if (startIdx !== -1 && endIdx !== -1) {\n base =\n existing.slice(0, startIdx).trimEnd() +\n '\\n' +\n existing.slice(endIdx + CUSTOM_RULES_END.length).trimStart();\n } else if (startIdx !== -1) {\n base = existing.slice(0, startIdx).trimEnd();\n } else {\n base = existing;\n }\n\n // Build the new custom-rules section\n const rulesBlock = [\n '',\n CUSTOM_RULES_START,\n ...customRules.map((r) => `- ${r}`),\n CUSTOM_RULES_END,\n ].join('\\n');\n\n const updated = base.trimEnd() + '\\n' + rulesBlock + '\\n';\n writeFileSync(rulesPath, updated, 'utf-8');\n}\n","/**\n * extension-manager.ts — Top-level orchestrator for the extension system.\n *\n * Coordinates the CapabilityRegistry, code generator, and guide updater\n * so that the rest of the system has a single entry-point for extension\n * operations.\n */\n\nimport { CapabilityRegistry } from './capability-registry.js';\nimport type {\n CapabilityType,\n Capability,\n} from './capability-registry.js';\nimport { generateCapability } from './generator.js';\nimport type { GenerateRequest } from './generator.js';\nimport { updatePluginGuide } from './guide-updater.js';\n\n// ---------------------------------------------------------------------------\n// Analysis result\n// ---------------------------------------------------------------------------\n\nexport interface AnalysisResult {\n needsNewCapability: boolean;\n suggestedType?: CapabilityType;\n suggestedName?: string;\n suggestedDescription?: string;\n suggestedTrigger?: string;\n}\n\n// ---------------------------------------------------------------------------\n// Creation result\n// ---------------------------------------------------------------------------\n\nexport interface CreateResult {\n capability: Capability;\n filePath: string;\n summary: string;\n}\n\n// ---------------------------------------------------------------------------\n// Keyword patterns for request analysis\n// ---------------------------------------------------------------------------\n\ninterface KeywordRule {\n type: CapabilityType;\n patterns: RegExp[];\n}\n\nconst KEYWORD_RULES: KeywordRule[] = [\n {\n type: 'hook',\n patterns: [\n /\\bevery\\s+time\\b/i,\n /\\balways\\b/i,\n /\\bbefore\\s+\\w+/i,\n /\\bafter\\s+\\w+/i,\n /\\bwhen\\s+\\w+/i,\n /\\bon\\s+(every|each)\\b/i,\n ],\n },\n {\n type: 'skill',\n patterns: [\n /\\/\\w+/,\n /\\bslash\\s+command\\b/i,\n /\\bshortcut\\b/i,\n /\\bskill\\b/i,\n ],\n },\n {\n type: 'asset',\n patterns: [\n /\\btemplate\\b/i,\n /\\bconfig\\b/i,\n /\\bsettings\\b/i,\n /\\bconfiguration\\b/i,\n ],\n },\n {\n type: 'loop',\n patterns: [\n /\\bcheck\\s+every\\b/i,\n /\\bpoll\\b/i,\n /\\bwatch\\b/i,\n /\\bmonitor\\b/i,\n /\\brepeatedly\\b/i,\n /\\bperiodically\\b/i,\n ],\n },\n];\n\n// ---------------------------------------------------------------------------\n// ExtensionManager\n// ---------------------------------------------------------------------------\n\nexport class ExtensionManager {\n private registry: CapabilityRegistry;\n\n constructor() {\n this.registry = new CapabilityRegistry();\n }\n\n /**\n * Initialize: load the registry from disk.\n */\n async init(): Promise<void> {\n await this.registry.loadAll();\n }\n\n /**\n * Analyze a user request to decide whether a new capability is needed.\n *\n * Uses keyword matching to suggest the capability type. Returns\n * `needsNewCapability: false` when the request matches an existing\n * capability name.\n */\n async analyzeRequest(request: string): Promise<AnalysisResult> {\n // If a capability with a matching name already exists, no creation needed\n const normalized = request.toLowerCase().trim();\n\n for (const cap of await this.registry.loadAll()) {\n if (normalized.includes(cap.name.toLowerCase())) {\n return { needsNewCapability: false };\n }\n }\n\n // Try to match keyword rules\n for (const rule of KEYWORD_RULES) {\n for (const pattern of rule.patterns) {\n if (pattern.test(request)) {\n const nameCandidate = extractName(request);\n return {\n needsNewCapability: true,\n suggestedType: rule.type,\n suggestedName: nameCandidate,\n suggestedDescription: request.slice(0, 120),\n suggestedTrigger: extractTrigger(request, rule.type),\n };\n }\n }\n }\n\n // Default: treat as a generic command\n return {\n needsNewCapability: true,\n suggestedType: 'command',\n suggestedName: extractName(request),\n suggestedDescription: request.slice(0, 120),\n suggestedTrigger: 'On user invocation',\n };\n }\n\n /**\n * Create a new capability, persist it, and update the plugin guide.\n */\n async createCapability(request: GenerateRequest): Promise<CreateResult> {\n // Generate the code file\n const result = generateCapability(request);\n\n // Register in the capability registry\n await this.registry.register(result.registryEntry);\n\n // Refresh the plugin guide so pre-read picks it up\n await updatePluginGuide(this.registry);\n\n // Build the full Capability object to return\n const capability: Capability = {\n ...result.registryEntry,\n createdAt: Date.now(),\n };\n\n const summary =\n `Created ${request.type} \"${request.name}\": ${request.description}. ` +\n `File: ${result.filePath}`;\n\n return { capability, filePath: result.filePath, summary };\n }\n\n /**\n * List all capabilities (built-in + custom).\n */\n async listCapabilities(): Promise<Capability[]> {\n return this.registry.loadAll();\n }\n\n /**\n * Remove a custom capability by name.\n *\n * Built-in capabilities cannot be removed.\n */\n async removeCapability(name: string): Promise<void> {\n const cap = this.registry.findByName(name);\n if (!cap) {\n throw new Error(`Capability not found: ${name}`);\n }\n if (cap.isBuiltIn) {\n throw new Error(`Cannot remove built-in capability: ${name}`);\n }\n\n await this.registry.unregister(cap.type, name);\n\n // Refresh the plugin guide\n await updatePluginGuide(this.registry);\n }\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Extract a reasonable short name from a user request string.\n */\nfunction extractName(request: string): string {\n // Try to pull out a slash-command name like /foo\n const slashMatch = request.match(/\\/(\\w[\\w-]*)/);\n if (slashMatch) return slashMatch[1];\n\n // Otherwise, take the first few meaningful words\n const words = request\n .replace(/[^a-zA-Z0-9\\s-]/g, '')\n .split(/\\s+/)\n .filter((w) => w.length > 2)\n .slice(0, 3);\n\n return words.join('-').toLowerCase() || 'unnamed';\n}\n\n/**\n * Generate a trigger description from the request and inferred type.\n */\nfunction extractTrigger(request: string, type: CapabilityType): string {\n switch (type) {\n case 'hook': {\n const beforeMatch = request.match(/before\\s+(\\w[\\w\\s]{0,30})/i);\n if (beforeMatch) return `Before ${beforeMatch[1].trim()}`;\n const afterMatch = request.match(/after\\s+(\\w[\\w\\s]{0,30})/i);\n if (afterMatch) return `After ${afterMatch[1].trim()}`;\n const whenMatch = request.match(/when\\s+(\\w[\\w\\s]{0,30})/i);\n if (whenMatch) return `When ${whenMatch[1].trim()}`;\n return 'On configured trigger';\n }\n case 'skill':\n return `/${extractName(request)}`;\n case 'loop': {\n const everyMatch = request.match(/every\\s+([\\w\\s]+)/i);\n if (everyMatch) return `Every ${everyMatch[1].trim()}`;\n return 'On interval';\n }\n case 'asset':\n return 'When referenced';\n case 'command':\n return 'On user invocation';\n }\n}\n","import { z } from 'zod';\nimport { costTracker } from '../utils/cost-tracker.js';\n\nexport const getCostSummarySchema = {\n meetingId: z.string().optional().describe('Optional meeting ID to filter costs'),\n};\n\nexport async function getCostSummaryHandler({\n meetingId,\n}: {\n meetingId?: string;\n}): Promise<{ content: { type: 'text'; text: string }[]; isError?: boolean }> {\n try {\n const summary = costTracker.getSummary(meetingId);\n const budgetWarning = costTracker.checkBudget();\n\n const result: Record<string, unknown> = {\n ...summary,\n };\n\n if (budgetWarning) {\n result.budgetWarning = budgetWarning;\n }\n\n if (meetingId) {\n result.filteredByMeeting = meetingId;\n }\n\n return {\n content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],\n };\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n return {\n content: [\n { type: 'text', text: JSON.stringify({ error: message }, null, 2) },\n ],\n isError: true,\n };\n }\n}\n","import { getDb } from '../storage/db.js';\n\n// ---------------------------------------------------------------------------\n// Cost summary\n// ---------------------------------------------------------------------------\n\nexport interface CostSummary {\n totalUsd: number;\n byMeeting: Record<string, number>;\n byDepartment: Record<string, number>;\n byTier: Record<string, number>;\n budgetLimit: number | null;\n budgetRemaining: number | null;\n}\n\n// ---------------------------------------------------------------------------\n// In-memory cost entry\n// ---------------------------------------------------------------------------\n\ninterface CostEntry {\n agentId: string;\n meetingId: string;\n costUsd: number;\n recordedAt: number;\n}\n\n// ---------------------------------------------------------------------------\n// CostTracker\n// ---------------------------------------------------------------------------\n\nexport class CostTracker {\n private budgetLimitUsd: number | null = null;\n private entries: CostEntry[] = [];\n\n /** Set a budget limit in USD. */\n setBudget(limitUsd: number): void {\n this.budgetLimitUsd = limitUsd;\n }\n\n /** Record a cost for an agent action. */\n recordCost(agentId: string, meetingId: string, costUsd: number): void {\n this.entries.push({\n agentId,\n meetingId,\n costUsd,\n recordedAt: Date.now(),\n });\n }\n\n /** Get the current cost summary, combining in-memory entries with DB data. */\n getSummary(meetingId?: string): CostSummary {\n const byMeeting: Record<string, number> = {};\n const byDepartment: Record<string, number> = {};\n const byTier: Record<string, number> = {};\n let totalUsd = 0;\n\n // 1. Aggregate from the agents table in the DB\n try {\n const db = getDb();\n\n interface AgentCostRow {\n meeting_id: string | null;\n department: string;\n tier: string;\n cost_usd: number;\n }\n\n let agentRows: AgentCostRow[];\n if (meetingId) {\n agentRows = db\n .prepare('SELECT meeting_id, department, tier, cost_usd FROM agents WHERE meeting_id = ?')\n .all(meetingId) as AgentCostRow[];\n } else {\n agentRows = db\n .prepare('SELECT meeting_id, department, tier, cost_usd FROM agents')\n .all() as AgentCostRow[];\n }\n\n for (const row of agentRows) {\n const cost = row.cost_usd ?? 0;\n if (cost === 0) continue;\n\n totalUsd += cost;\n const mid = row.meeting_id ?? 'unknown';\n byMeeting[mid] = (byMeeting[mid] ?? 0) + cost;\n byDepartment[row.department] = (byDepartment[row.department] ?? 0) + cost;\n byTier[row.tier] = (byTier[row.tier] ?? 0) + cost;\n }\n\n // 2. Aggregate from the workers table\n interface WorkerCostRow {\n meeting_id: string;\n cost_usd: number;\n leader_id: string;\n }\n\n let workerRows: WorkerCostRow[];\n if (meetingId) {\n workerRows = db\n .prepare('SELECT meeting_id, cost_usd, leader_id FROM workers WHERE meeting_id = ?')\n .all(meetingId) as WorkerCostRow[];\n } else {\n workerRows = db\n .prepare('SELECT meeting_id, cost_usd, leader_id FROM workers')\n .all() as WorkerCostRow[];\n }\n\n for (const row of workerRows) {\n const cost = row.cost_usd ?? 0;\n if (cost === 0) continue;\n\n totalUsd += cost;\n byMeeting[row.meeting_id] = (byMeeting[row.meeting_id] ?? 0) + cost;\n byTier['worker'] = (byTier['worker'] ?? 0) + cost;\n\n // Look up the leader's department for the worker\n interface LeaderDeptRow { department: string }\n const leader = db\n .prepare('SELECT department FROM agents WHERE id = ?')\n .get(row.leader_id) as LeaderDeptRow | undefined;\n if (leader) {\n byDepartment[leader.department] = (byDepartment[leader.department] ?? 0) + cost;\n }\n }\n } catch {\n // DB might not be initialised yet; fall through to in-memory only\n }\n\n // 3. Aggregate in-memory entries\n const filteredEntries = meetingId\n ? this.entries.filter((e) => e.meetingId === meetingId)\n : this.entries;\n\n for (const entry of filteredEntries) {\n totalUsd += entry.costUsd;\n byMeeting[entry.meetingId] = (byMeeting[entry.meetingId] ?? 0) + entry.costUsd;\n }\n\n return {\n totalUsd,\n byMeeting,\n byDepartment,\n byTier,\n budgetLimit: this.budgetLimitUsd,\n budgetRemaining: this.budgetLimitUsd !== null ? this.budgetLimitUsd - totalUsd : null,\n };\n }\n\n /** Check if over budget. Returns a warning message or null. */\n checkBudget(): string | null {\n if (this.budgetLimitUsd === null) return null;\n\n const summary = this.getSummary();\n if (summary.totalUsd >= this.budgetLimitUsd) {\n return `Budget exceeded: $${summary.totalUsd.toFixed(4)} spent of $${this.budgetLimitUsd.toFixed(4)} limit`;\n }\n\n const remaining = this.budgetLimitUsd - summary.totalUsd;\n if (remaining < this.budgetLimitUsd * 0.1) {\n return `Budget warning: $${summary.totalUsd.toFixed(4)} spent, only $${remaining.toFixed(4)} remaining of $${this.budgetLimitUsd.toFixed(4)} limit`;\n }\n\n return null;\n }\n}\n\n/** Shared singleton instance. */\nexport const costTracker = new CostTracker();\n","import { z } from 'zod';\nimport { Orchestrator } from '../orchestrator/orchestrator.js';\nimport type { Department } from '../types/index.js';\n\nexport const chainMeetingSchema = {\n previousMeetingId: z.string().describe('ID of the previous meeting to chain from'),\n topic: z.string().describe('Topic for the new chained meeting'),\n agenda: z.array(z.string()).describe('Agenda items for the new meeting'),\n departments: z\n .array(z.string())\n .optional()\n .describe('Specific departments to invite'),\n};\n\nexport async function chainMeetingHandler({\n previousMeetingId,\n topic,\n agenda,\n departments,\n}: {\n previousMeetingId: string;\n topic: string;\n agenda: string[];\n departments?: string[];\n}): Promise<{ content: { type: 'text'; text: string }[]; isError?: boolean }> {\n try {\n const orchestrator = new Orchestrator();\n const meetingId = await orchestrator.chainMeeting({\n previousMeetingId,\n topic,\n agenda,\n departments: departments as Department[] | undefined,\n });\n\n const result = {\n meetingId,\n status: 'started',\n chainedFrom: previousMeetingId,\n topic,\n agenda,\n departments: departments ?? orchestrator.selectLeaders(topic, agenda),\n };\n\n return {\n content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],\n };\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n return {\n content: [\n { type: 'text', text: JSON.stringify({ error: message }, null, 2) },\n ],\n isError: true,\n };\n }\n}\n","import { createServer as createHttpServer } from 'node:http';\nimport { WebSocketServer, WebSocket } from 'ws';\nimport { getDashboardHTML } from './html.js';\nimport { StateBridge } from './state-bridge.js';\nimport { DashboardClient } from './client.js';\nimport { eventBus } from '../orchestrator/event-bus.js';\nimport { getConfig } from '../utils/config.js';\nimport { logger } from '../utils/logger.js';\nimport type { AgentEvent, ServerMessage } from '../types/dashboard-events.js';\n\nexport interface DashboardHandle {\n isOwner: boolean;\n close: () => void;\n}\n\nexport interface DashboardOptions {\n sessionId: string;\n projectPath: string;\n projectName: string;\n}\n\nexport function startDashboard(options: DashboardOptions): Promise<DashboardHandle> {\n const port = getConfig().DASHBOARD_PORT;\n\n return new Promise((resolve) => {\n const httpServer = createHttpServer((req, res) => {\n if (req.url === '/' || req.url === '/index.html') {\n res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' });\n res.end(getDashboardHTML());\n } else {\n res.writeHead(404);\n res.end('Not Found');\n }\n });\n\n httpServer.on('error', (err: NodeJS.ErrnoException) => {\n if (err.code === 'EADDRINUSE') {\n // Port in use — become a client\n logger.info(`Dashboard port ${port} in use — connecting as client`);\n const client = new DashboardClient(options.sessionId, options.projectName, options.projectPath);\n client.connect(port);\n resolve({\n isOwner: false,\n close: () => client.disconnect(),\n });\n } else {\n logger.error(`Dashboard error: ${err.message}`);\n resolve({ isOwner: false, close: () => {} });\n }\n });\n\n httpServer.listen(port, '127.0.0.1', () => {\n logger.info(`Dashboard owner — running at http://localhost:${port}`);\n\n const wss = new WebSocketServer({ server: httpServer });\n const bridge = new StateBridge();\n\n // Register own session\n const displayName = bridge.registerSession({\n sessionId: options.sessionId,\n projectPath: options.projectPath,\n projectName: options.projectName,\n });\n logger.info(`Registered own session: ${displayName}`);\n\n // Forward local events to bridge\n eventBus.on('agent_event', (event: AgentEvent) => {\n bridge.handleSessionEvent(options.sessionId, event);\n });\n\n // Handle browser clients + MCP server clients\n wss.on('connection', (ws: WebSocket) => {\n // Send full snapshot\n ws.send(JSON.stringify(bridge.getSnapshot()));\n\n ws.on('message', (data: Buffer) => {\n try {\n const msg: ServerMessage = JSON.parse(data.toString());\n\n if (msg.type === 'register') {\n const name = bridge.registerSession({\n sessionId: msg.sessionId,\n projectPath: msg.projectPath,\n projectName: msg.projectName,\n });\n // Notify all browser clients\n const notification = JSON.stringify({\n type: 'session-registered',\n sessionId: msg.sessionId,\n displayName: name,\n projectPath: msg.projectPath,\n });\n wss.clients.forEach((c) => {\n if (c !== ws && c.readyState === WebSocket.OPEN) c.send(notification);\n });\n } else if (msg.type === 'session-event') {\n bridge.handleSessionEvent(msg.sessionId, msg.event);\n } else if (msg.type === 'unregister') {\n bridge.unregisterSession(msg.sessionId);\n const notification = JSON.stringify({\n type: 'session-unregistered',\n sessionId: msg.sessionId,\n });\n wss.clients.forEach((c) => {\n if (c.readyState === WebSocket.OPEN) c.send(notification);\n });\n } else if ((msg as any).type === 'ping') {\n ws.send(JSON.stringify({ type: 'pong' }));\n }\n } catch {\n // ignore malformed\n }\n });\n });\n\n // Broadcast deltas to all browser clients\n bridge.on('broadcast', (data: string) => {\n wss.clients.forEach((c) => {\n if (c.readyState === WebSocket.OPEN) c.send(data);\n });\n });\n\n resolve({\n isOwner: true,\n close: () => {\n bridge.unregisterSession(options.sessionId);\n wss.close();\n httpServer.close();\n },\n });\n });\n });\n}\n","/**\n * getDashboardHTML() — returns the full inline HTML/CSS/JS for the Open Coleslaw\n * real-time dashboard. Everything is self-contained; the only external deps are\n * Cytoscape.js + dagre loaded from CDN.\n *\n * Multi-session aware: one tab per project session in the tab bar.\n */\n\nexport function getDashboardHTML(): string {\n return /* html */ `<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n<meta charset=\"utf-8\" />\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" />\n<title>Open Coleslaw Dashboard</title>\n\n<!-- CDN deps -->\n<script src=\"https://cdnjs.cloudflare.com/ajax/libs/cytoscape/3.30.4/cytoscape.min.js\"></script>\n<script src=\"https://cdnjs.cloudflare.com/ajax/libs/dagre/0.8.5/dagre.min.js\"></script>\n<script src=\"https://unpkg.com/cytoscape-dagre@2.5.0/cytoscape-dagre.js\"></script>\n\n<!-- Google Fonts: JetBrains Mono -->\n<link rel=\"preconnect\" href=\"https://fonts.googleapis.com\" />\n<link rel=\"preconnect\" href=\"https://fonts.gstatic.com\" crossorigin />\n<link href=\"https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@300;400;500;600;700&display=swap\" rel=\"stylesheet\" />\n\n<style>\n/* ===================================================================\n RESET & VARIABLES\n =================================================================== */\n*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }\n\n:root {\n --bg: #0a0e17;\n --surface: #111827;\n --border: #1e293b;\n --cyan: #00f0ff;\n --purple: #a855f7;\n --lightcyan: #22d3ee;\n --success: #10b981;\n --warning: #f59e0b;\n --error: #ef4444;\n --text: #e2e8f0;\n --text2: #94a3b8;\n --font: 'JetBrains Mono', 'Fira Code', monospace;\n}\n\nhtml, body {\n width: 100%; height: 100%;\n overflow: hidden;\n background: var(--bg);\n color: var(--text);\n font-family: var(--font);\n font-size: 13px;\n line-height: 1.5;\n}\n\n/* ===================================================================\n LAYOUT — five areas via CSS Grid\n =================================================================== */\n#app {\n display: grid;\n width: 100%; height: 100%;\n grid-template-rows: 48px 36px 1fr 200px;\n grid-template-columns: 1fr 320px;\n grid-template-areas:\n \"header header\"\n \"tabs tabs\"\n \"graph sidebar\"\n \"log log\";\n}\n\n/* ===================================================================\n HEADER\n =================================================================== */\n#header {\n grid-area: header;\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 0 20px;\n background: var(--surface);\n border-bottom: 1px solid var(--border);\n gap: 16px;\n z-index: 10;\n}\n\n#header .brand {\n display: flex;\n align-items: center;\n gap: 10px;\n font-size: 16px;\n font-weight: 700;\n color: var(--cyan);\n text-shadow: 0 0 12px rgba(0,240,255,0.5);\n white-space: nowrap;\n}\n\n#header .center-status {\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 12px;\n}\n\n.conn-dot {\n width: 10px; height: 10px;\n border-radius: 50%;\n background: var(--error);\n transition: background 0.3s;\n box-shadow: 0 0 6px rgba(239,68,68,0.6);\n}\n.conn-dot.connected {\n background: var(--success);\n box-shadow: 0 0 6px rgba(16,185,129,0.6);\n}\n.conn-dot.reconnecting {\n background: var(--warning);\n box-shadow: 0 0 6px rgba(245,158,11,0.6);\n animation: breathe 1.5s ease-in-out infinite;\n}\n\n#header .right-stats {\n display: flex;\n align-items: center;\n gap: 14px;\n font-size: 12px;\n}\n\n.badge {\n background: rgba(0,240,255,0.1);\n border: 1px solid rgba(0,240,255,0.25);\n padding: 2px 10px;\n border-radius: 12px;\n font-size: 11px;\n white-space: nowrap;\n}\n.badge.purple { background: rgba(168,85,247,0.1); border-color: rgba(168,85,247,0.3); }\n.badge.amber { background: rgba(245,158,11,0.1); border-color: rgba(245,158,11,0.3); color: var(--warning); }\n.badge.green { background: rgba(16,185,129,0.1); border-color: rgba(16,185,129,0.3); color: var(--success); }\n\n/* ===================================================================\n TAB BAR\n =================================================================== */\n#tab-bar {\n grid-area: tabs;\n display: flex;\n align-items: stretch;\n background: var(--surface);\n border-bottom: 1px solid var(--border);\n padding: 0 12px;\n gap: 2px;\n overflow-x: auto;\n overflow-y: hidden;\n scrollbar-width: none;\n}\n#tab-bar::-webkit-scrollbar { display: none; }\n\n.session-tab {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 0 14px;\n font-size: 11px;\n font-family: var(--font);\n font-weight: 500;\n color: var(--text2);\n background: transparent;\n border: none;\n border-bottom: 2px solid transparent;\n cursor: pointer;\n white-space: nowrap;\n transition: color 0.2s, border-color 0.2s, opacity 0.2s;\n position: relative;\n}\n.session-tab:hover {\n color: var(--text);\n background: rgba(255,255,255,0.02);\n}\n.session-tab.active {\n color: var(--cyan);\n border-bottom-color: var(--cyan);\n text-shadow: 0 0 8px rgba(0,240,255,0.4);\n}\n.session-tab.inactive {\n opacity: 0.45;\n text-decoration: line-through;\n color: var(--text2);\n}\n.session-tab.inactive:hover {\n opacity: 0.6;\n}\n\n.tab-badge {\n font-size: 9px;\n padding: 1px 5px;\n border-radius: 8px;\n background: rgba(0,240,255,0.15);\n color: var(--cyan);\n font-weight: 700;\n min-width: 16px;\n text-align: center;\n}\n.tab-badge.meeting {\n background: rgba(245,158,11,0.2);\n color: var(--warning);\n}\n\n.tab-empty-msg {\n display: flex;\n align-items: center;\n font-size: 11px;\n color: var(--text2);\n font-style: italic;\n padding: 0 8px;\n}\n\n/* ===================================================================\n GRAPH VIEWPORT\n =================================================================== */\n#graph-container {\n grid-area: graph;\n background: var(--bg);\n position: relative;\n overflow: hidden;\n}\n#cy {\n width: 100%; height: 100%;\n}\n/* watermark text */\n#graph-container::after {\n content: 'AGENT GRAPH';\n position: absolute;\n bottom: 12px; left: 16px;\n font-size: 10px;\n color: rgba(148,163,184,0.25);\n letter-spacing: 3px;\n pointer-events: none;\n}\n\n/* ===================================================================\n SIDEBAR\n =================================================================== */\n#sidebar {\n grid-area: sidebar;\n background: var(--surface);\n border-left: 1px solid var(--border);\n padding: 16px;\n overflow-y: auto;\n display: flex;\n flex-direction: column;\n gap: 12px;\n}\n\n#sidebar h2 {\n font-size: 12px;\n text-transform: uppercase;\n letter-spacing: 2px;\n color: var(--text2);\n margin-bottom: 4px;\n}\n\n.sidebar-empty {\n color: var(--text2);\n font-style: italic;\n font-size: 12px;\n margin-top: 40px;\n text-align: center;\n}\n\n.detail-row {\n display: flex;\n justify-content: space-between;\n padding: 4px 0;\n border-bottom: 1px solid var(--border);\n font-size: 12px;\n}\n.detail-row .label { color: var(--text2); }\n.detail-row .value { color: var(--text); font-weight: 500; }\n\n.status-chip {\n display: inline-block;\n padding: 1px 8px;\n border-radius: 6px;\n font-size: 11px;\n font-weight: 600;\n}\n.status-chip.idle { background: rgba(148,163,184,0.15); color: var(--text2); }\n.status-chip.working { background: rgba(0,240,255,0.15); color: var(--cyan); }\n.status-chip.in-meeting { background: rgba(245,158,11,0.15); color: var(--warning); }\n.status-chip.spawning-workers { background: rgba(168,85,247,0.15); color: var(--purple); }\n.status-chip.aggregating { background: rgba(34,211,238,0.15); color: var(--lightcyan); }\n.status-chip.waiting-for-user { background: rgba(245,158,11,0.15); color: var(--warning); }\n.status-chip.completed { background: rgba(16,185,129,0.15); color: var(--success); }\n.status-chip.failed { background: rgba(239,68,68,0.15); color: var(--error); }\n\n.task-block {\n background: rgba(0,0,0,0.3);\n border: 1px solid var(--border);\n border-radius: 6px;\n padding: 10px;\n font-size: 12px;\n color: var(--text2);\n line-height: 1.6;\n max-height: 160px;\n overflow-y: auto;\n}\n\n/* Children list */\n.children-list {\n list-style: none;\n padding: 0;\n font-size: 12px;\n}\n.children-list li {\n padding: 3px 0;\n display: flex;\n align-items: center;\n gap: 6px;\n}\n.children-list li::before {\n content: '';\n display: inline-block;\n width: 6px; height: 6px;\n border-radius: 50%;\n background: var(--lightcyan);\n}\n\n/* Task history */\n#task-history {\n max-height: 250px;\n overflow-y: auto;\n}\n.history-item {\n font-size: 11px;\n padding: 4px 0;\n border-bottom: 1px solid rgba(30,41,59,0.5);\n color: var(--text2);\n}\n\n/* ===================================================================\n EVENT LOG\n =================================================================== */\n#event-log {\n grid-area: log;\n background: var(--surface);\n border-top: 1px solid var(--border);\n display: flex;\n flex-direction: column;\n overflow: hidden;\n}\n\n#event-log .log-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 6px 16px;\n font-size: 10px;\n text-transform: uppercase;\n letter-spacing: 2px;\n color: var(--text2);\n border-bottom: 1px solid var(--border);\n flex-shrink: 0;\n}\n#event-log .log-header .pause-indicator {\n color: var(--warning);\n font-weight: 600;\n display: none;\n}\n#event-log .log-header .pause-indicator.visible {\n display: inline;\n}\n\n#log-entries {\n flex: 1;\n overflow-y: auto;\n padding: 4px 0;\n font-size: 12px;\n scroll-behavior: smooth;\n}\n\n.log-entry {\n display: flex;\n gap: 12px;\n padding: 3px 16px;\n border-bottom: 1px solid rgba(30,41,59,0.3);\n align-items: baseline;\n}\n.log-entry:hover { background: rgba(255,255,255,0.02); }\n\n.log-time {\n color: var(--text2);\n font-size: 11px;\n flex-shrink: 0;\n min-width: 64px;\n}\n.log-session {\n color: var(--cyan);\n font-size: 10px;\n flex-shrink: 0;\n min-width: 80px;\n max-width: 120px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n opacity: 0.7;\n}\n.log-kind {\n font-weight: 600;\n flex-shrink: 0;\n min-width: 90px;\n font-size: 11px;\n}\n.log-msg {\n color: var(--text);\n flex: 1;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n/* Kind colours */\n.log-kind.spawn { color: var(--cyan); }\n.log-kind.destroy { color: var(--error); }\n.log-kind.state { color: var(--purple); }\n.log-kind.task { color: var(--lightcyan); }\n.log-kind.done { color: var(--success); }\n.log-kind.msg { color: var(--text); }\n.log-kind.mention { color: var(--error); }\n.log-kind.resolved { color: var(--success); }\n.log-kind.cost { color: var(--warning); }\n.log-kind.session { color: var(--purple); }\n\n/* ===================================================================\n ANIMATIONS\n =================================================================== */\n@keyframes breathe {\n 0%, 100% { opacity: 0.4; }\n 50% { opacity: 1; }\n}\n@keyframes pulse-glow {\n 0%, 100% { box-shadow: 0 0 4px rgba(0,240,255,0.3); }\n 50% { box-shadow: 0 0 18px rgba(0,240,255,0.7); }\n}\n\n/* Custom scrollbar */\n::-webkit-scrollbar { width: 6px; }\n::-webkit-scrollbar-track { background: var(--bg); }\n::-webkit-scrollbar-thumb { background: var(--border); border-radius: 3px; }\n::-webkit-scrollbar-thumb:hover { background: #334155; }\n</style>\n</head>\n<body>\n\n<div id=\"app\">\n <!-- HEADER ------------------------------------------------------------ -->\n <header id=\"header\">\n <div class=\"brand\">\n <span style=\"font-size:22px\">&#x1F96C;</span>\n <span>Open Coleslaw</span>\n </div>\n <div class=\"center-status\">\n <span class=\"conn-dot\" id=\"conn-dot\"></span>\n <span id=\"conn-label\">Connecting...</span>\n </div>\n <div class=\"right-stats\">\n <span class=\"badge\" id=\"badge-sessions\">0 sessions</span>\n <span class=\"badge\" id=\"badge-agents\">0 agents</span>\n <span class=\"badge purple\" id=\"badge-meeting\">No meeting</span>\n <span class=\"badge green\" id=\"badge-cost\">$0.0000</span>\n </div>\n </header>\n\n <!-- TAB BAR ----------------------------------------------------------- -->\n <div id=\"tab-bar\">\n <span class=\"tab-empty-msg\" id=\"tab-empty\">Waiting for sessions...</span>\n </div>\n\n <!-- GRAPH ------------------------------------------------------------- -->\n <div id=\"graph-container\">\n <div id=\"cy\"></div>\n </div>\n\n <!-- SIDEBAR ----------------------------------------------------------- -->\n <aside id=\"sidebar\">\n <h2>Agent Details</h2>\n <div class=\"sidebar-empty\" id=\"sidebar-empty\">Click a node to inspect</div>\n <div id=\"sidebar-content\" style=\"display:none;\"></div>\n </aside>\n\n <!-- EVENT LOG --------------------------------------------------------- -->\n <div id=\"event-log\">\n <div class=\"log-header\">\n <span>Event Log</span>\n <span class=\"pause-indicator\" id=\"log-pause\">PAUSED (scroll up)</span>\n </div>\n <div id=\"log-entries\"></div>\n </div>\n</div>\n\n<script>\n// ======================================================================\n// IIFE -- all dashboard JS\n// ======================================================================\n(function () {\n 'use strict';\n\n // ====================================================================\n // 1. STATE STORE (per-session)\n // ====================================================================\n // sessions: Map<sessionId, { displayName, projectPath, isActive, agents: Map, edges: [], meeting, totalCost, eventHistory[] }>\n const sessions = new Map();\n let activeTabId = null; // currently viewed session\n let selectedAgentId = null; // clicked node\n\n function getSession(id) { return sessions.get(id); }\n\n function activeSession() {\n if (!activeTabId) return null;\n return sessions.get(activeTabId) || null;\n }\n\n // ====================================================================\n // 2. CONNECTION MANAGER -- WebSocket with exponential backoff\n // ====================================================================\n const ConnectionManager = {\n ws: null,\n backoff: 1000,\n maxBackoff: 30000,\n timer: null,\n _heartbeat: null,\n\n connect() {\n const proto = location.protocol === 'https:' ? 'wss' : 'ws';\n const url = proto + '://' + location.host;\n this.ws = new WebSocket(url);\n this.setStatus('reconnecting');\n\n this.ws.onopen = () => {\n this.backoff = 1000;\n this.setStatus('connected');\n };\n\n this.ws.onmessage = (msg) => {\n try {\n const data = JSON.parse(msg.data);\n this.handleMessage(data);\n } catch (e) {\n console.error('[WS] Parse error:', e);\n }\n };\n\n this.ws.onclose = () => {\n this.setStatus('disconnected');\n this.scheduleReconnect();\n };\n\n this.ws.onerror = () => {};\n\n if (this._heartbeat) clearInterval(this._heartbeat);\n this._heartbeat = setInterval(() => {\n if (this.ws && this.ws.readyState === WebSocket.OPEN) {\n this.ws.send(JSON.stringify({ type: 'ping' }));\n }\n }, 25000);\n },\n\n handleMessage(data) {\n switch (data.type) {\n case 'multi-snapshot':\n this.handleMultiSnapshot(data);\n break;\n case 'session-delta':\n this.handleSessionDelta(data);\n break;\n case 'session-registered':\n this.handleSessionRegistered(data);\n break;\n case 'session-unregistered':\n this.handleSessionUnregistered(data);\n break;\n case 'pong':\n break;\n default:\n break;\n }\n },\n\n handleMultiSnapshot(data) {\n sessions.clear();\n (data.sessions || []).forEach(function (s) {\n var agentsMap = new Map();\n (s.snapshot.agents || []).forEach(function (a) { agentsMap.set(a.id, a); });\n sessions.set(s.sessionId, {\n displayName: s.displayName,\n projectPath: s.projectPath,\n isActive: s.isActive,\n agents: agentsMap,\n edges: s.snapshot.edges || [],\n meeting: s.snapshot.meeting || null,\n totalCost: s.snapshot.totalCost || 0,\n eventHistory: [],\n });\n });\n // Auto-select first active tab if none selected\n if (!activeTabId || !sessions.has(activeTabId)) {\n var first = null;\n sessions.forEach(function (s, id) { if (!first && s.isActive) first = id; });\n if (!first && sessions.size > 0) first = sessions.keys().next().value;\n activeTabId = first;\n }\n TabBar.render();\n StatusBar.update();\n GraphRenderer.rebuild();\n },\n\n handleSessionDelta(data) {\n var sess = sessions.get(data.sessionId);\n if (!sess) {\n // Session not yet known -- create a placeholder\n sess = {\n displayName: data.displayName,\n projectPath: '',\n isActive: true,\n agents: new Map(),\n edges: [],\n meeting: null,\n totalCost: 0,\n eventHistory: [],\n };\n sessions.set(data.sessionId, sess);\n TabBar.render();\n }\n\n (data.events || []).forEach(function (ev) {\n applyEventToSession(data.sessionId, sess, ev);\n });\n\n TabBar.updateBadge(data.sessionId);\n StatusBar.update();\n\n // Rebuild graph only if this is the active tab\n if (data.sessionId === activeTabId) {\n GraphRenderer.rebuild();\n if (selectedAgentId) SidebarPanel.show(selectedAgentId);\n }\n },\n\n handleSessionRegistered(data) {\n if (!sessions.has(data.sessionId)) {\n sessions.set(data.sessionId, {\n displayName: data.displayName,\n projectPath: data.projectPath,\n isActive: true,\n agents: new Map(),\n edges: [],\n meeting: null,\n totalCost: 0,\n eventHistory: [],\n });\n }\n // Auto-select if no tab is active\n if (!activeTabId) activeTabId = data.sessionId;\n TabBar.render();\n StatusBar.update();\n EventLog.appendSystem(data.displayName, 'Session connected');\n },\n\n handleSessionUnregistered(data) {\n var sess = sessions.get(data.sessionId);\n if (sess) {\n sess.isActive = false;\n TabBar.render();\n StatusBar.update();\n EventLog.appendSystem(sess.displayName, 'Session disconnected');\n }\n },\n\n scheduleReconnect() {\n if (this.timer) clearTimeout(this.timer);\n this.timer = setTimeout(() => {\n this.backoff = Math.min(this.backoff * 2, this.maxBackoff);\n this.connect();\n }, this.backoff);\n },\n\n setStatus(status) {\n var dot = document.getElementById('conn-dot');\n var label = document.getElementById('conn-label');\n dot.className = 'conn-dot';\n if (status === 'connected') {\n dot.classList.add('connected');\n label.textContent = 'Connected';\n } else if (status === 'reconnecting') {\n dot.classList.add('reconnecting');\n label.textContent = 'Connecting...';\n } else {\n label.textContent = 'Disconnected';\n }\n },\n };\n\n // ====================================================================\n // Event application (scoped to a session)\n // ====================================================================\n function applyEventToSession(sessionId, sess, ev) {\n sess.eventHistory.push(ev);\n if (sess.eventHistory.length > 500) sess.eventHistory.shift();\n\n EventLog.append(sessionId, sess.displayName, ev);\n\n switch (ev.kind) {\n case 'agent_spawned': {\n var agent = {\n id: ev.agentId,\n type: ev.agentType,\n label: ev.label,\n status: 'idle',\n parentId: ev.parentId,\n department: ev.department,\n currentTask: null,\n costUsd: 0,\n };\n sess.agents.set(ev.agentId, agent);\n if (ev.parentId) {\n sess.edges.push({\n id: 'edge-' + ev.parentId + '-' + ev.agentId,\n source: ev.parentId,\n target: ev.agentId,\n edgeType: 'hierarchy',\n active: true,\n label: '',\n });\n }\n break;\n }\n case 'agent_destroyed': {\n sess.agents.delete(ev.agentId);\n sess.edges = sess.edges.filter(function (e) {\n return e.source !== ev.agentId && e.target !== ev.agentId;\n });\n if (sessionId === activeTabId && selectedAgentId === ev.agentId) {\n selectedAgentId = null;\n SidebarPanel.clear();\n }\n break;\n }\n case 'state_changed': {\n var a = sess.agents.get(ev.agentId);\n if (a) a.status = ev.to;\n break;\n }\n case 'task_assigned': {\n var a = sess.agents.get(ev.agentId);\n if (a) { a.currentTask = ev.taskSummary; a.status = 'working'; }\n break;\n }\n case 'task_completed': {\n var a = sess.agents.get(ev.agentId);\n if (a) { a.currentTask = null; a.status = ev.result === 'success' ? 'completed' : 'failed'; }\n break;\n }\n case 'message_sent': {\n var edgeId = 'msg-' + ev.fromId + '-' + ev.toId + '-' + Date.now();\n var edge = { id: edgeId, source: ev.fromId, target: ev.toId, edgeType: 'message', active: true, label: ev.summary };\n sess.edges.push(edge);\n setTimeout(function () {\n sess.edges = sess.edges.filter(function (e) { return e.id !== edgeId; });\n if (sessionId === activeTabId) GraphRenderer.rebuild();\n }, 5000);\n break;\n }\n case 'cost_update': {\n sess.totalCost = ev.totalCost;\n break;\n }\n default:\n break;\n }\n }\n\n // ====================================================================\n // 3. TAB BAR\n // ====================================================================\n var TabBar = {\n render: function () {\n var bar = document.getElementById('tab-bar');\n var emptyMsg = document.getElementById('tab-empty');\n\n // Remove old tabs (keep the empty msg span)\n var old = bar.querySelectorAll('.session-tab');\n old.forEach(function (el) { el.remove(); });\n\n if (sessions.size === 0) {\n emptyMsg.style.display = '';\n return;\n }\n emptyMsg.style.display = 'none';\n\n sessions.forEach(function (sess, sessionId) {\n var tab = document.createElement('button');\n tab.className = 'session-tab';\n if (sessionId === activeTabId) tab.classList.add('active');\n if (!sess.isActive) tab.classList.add('inactive');\n tab.dataset.sessionId = sessionId;\n\n // Tab label\n var lbl = document.createElement('span');\n lbl.textContent = sess.displayName || sessionId.slice(0, 8);\n tab.appendChild(lbl);\n\n // Agent count badge\n var badge = document.createElement('span');\n badge.className = 'tab-badge';\n badge.textContent = String(sess.agents.size);\n tab.appendChild(badge);\n\n // Meeting indicator\n if (sess.meeting) {\n var mb = document.createElement('span');\n mb.className = 'tab-badge meeting';\n mb.textContent = 'MTG';\n tab.appendChild(mb);\n }\n\n tab.addEventListener('click', function () {\n TabBar.switchTo(sessionId);\n });\n\n bar.appendChild(tab);\n });\n },\n\n switchTo: function (sessionId) {\n activeTabId = sessionId;\n selectedAgentId = null;\n SidebarPanel.clear();\n this.render();\n StatusBar.update();\n GraphRenderer.rebuild();\n },\n\n updateBadge: function (sessionId) {\n var bar = document.getElementById('tab-bar');\n var tabs = bar.querySelectorAll('.session-tab');\n tabs.forEach(function (tab) {\n if (tab.dataset.sessionId === sessionId) {\n var sess = sessions.get(sessionId);\n if (!sess) return;\n var badge = tab.querySelector('.tab-badge:not(.meeting)');\n if (badge) badge.textContent = String(sess.agents.size);\n }\n });\n },\n };\n\n // ====================================================================\n // 4. GRAPH RENDERER -- Cytoscape.js\n // ====================================================================\n var GraphRenderer = {\n cy: null,\n _layoutTimer: null,\n _animFrame: null,\n _dashOffset: 0,\n\n init: function () {\n this.cy = cytoscape({\n container: document.getElementById('cy'),\n style: [\n // --- NODES ---\n {\n selector: 'node',\n style: {\n 'label': 'data(label)',\n 'text-valign': 'bottom',\n 'text-halign': 'center',\n 'text-margin-y': 8,\n 'font-family': \"'JetBrains Mono', monospace\",\n 'font-size': 10,\n 'color': '#94a3b8',\n 'text-outline-width': 0,\n 'background-color': '#1e293b',\n 'border-width': 2,\n 'border-color': '#334155',\n 'width': 40,\n 'height': 40,\n 'transition-property': 'background-color, border-color, border-width, opacity, width, height',\n 'transition-duration': '0.3s',\n },\n },\n // Orchestrator\n {\n selector: 'node[tier=\"orchestrator\"]',\n style: {\n 'width': 60, 'height': 60,\n 'border-width': 3,\n 'border-color': '#00f0ff',\n 'background-color': 'rgba(0,240,255,0.1)',\n 'color': '#00f0ff',\n 'font-size': 12, 'font-weight': '700',\n 'text-outline-color': '#0a0e17',\n 'text-outline-width': 2,\n },\n },\n // Leader\n {\n selector: 'node[tier=\"leader\"]',\n style: {\n 'width': 48, 'height': 48,\n 'border-width': 2,\n 'border-color': '#a855f7',\n 'background-color': 'rgba(168,85,247,0.1)',\n 'color': '#a855f7',\n 'font-size': 11, 'font-weight': '600',\n },\n },\n // Worker\n {\n selector: 'node[tier=\"worker\"]',\n style: {\n 'width': 36, 'height': 36,\n 'border-width': 2,\n 'border-color': '#22d3ee',\n 'background-color': 'rgba(34,211,238,0.08)',\n 'color': '#22d3ee',\n 'font-size': 10,\n },\n },\n // Status: idle\n { selector: 'node[status=\"idle\"]', style: { 'opacity': 0.5, 'border-color': '#475569' } },\n // Status: working\n { selector: 'node[status=\"working\"]', style: { 'border-width': 3, 'opacity': 1 } },\n // Status: in-meeting\n { selector: 'node[status=\"in-meeting\"]', style: { 'border-color': '#f59e0b', 'background-color': 'rgba(245,158,11,0.1)', 'opacity': 1 } },\n // Status: spawning-workers\n { selector: 'node[status=\"spawning-workers\"]', style: { 'border-color': '#a855f7', 'opacity': 1 } },\n // Status: waiting-for-user\n { selector: 'node[status=\"waiting-for-user\"]', style: { 'border-color': '#f59e0b', 'opacity': 0.8 } },\n // Status: aggregating\n { selector: 'node[status=\"aggregating\"]', style: { 'border-color': '#22d3ee', 'opacity': 1 } },\n // Status: completed\n { selector: 'node[status=\"completed\"]', style: { 'border-color': '#10b981', 'background-color': 'rgba(16,185,129,0.1)', 'opacity': 0.7 } },\n // Status: failed\n { selector: 'node[status=\"failed\"]', style: { 'border-color': '#ef4444', 'background-color': 'rgba(239,68,68,0.1)', 'opacity': 0.8 } },\n // Selected node\n { selector: 'node:selected', style: { 'border-width': 4, 'overlay-padding': 6, 'overlay-color': '#00f0ff', 'overlay-opacity': 0.08 } },\n // --- EDGES ---\n {\n selector: 'edge',\n style: {\n 'width': 1.5,\n 'line-color': '#334155',\n 'target-arrow-color': '#334155',\n 'target-arrow-shape': 'triangle',\n 'arrow-scale': 0.8,\n 'curve-style': 'bezier',\n 'opacity': 0.5,\n 'transition-property': 'line-color, opacity, width',\n 'transition-duration': '0.3s',\n },\n },\n { selector: 'edge[edgeType=\"hierarchy\"][?active]', style: { 'line-color': '#475569', 'target-arrow-color': '#475569', 'line-style': 'solid', 'opacity': 0.6, 'width': 1.5 } },\n { selector: 'edge[edgeType=\"delegation\"]', style: { 'line-color': '#a855f7', 'target-arrow-color': '#a855f7', 'line-style': 'dashed', 'line-dash-pattern': [8, 4], 'opacity': 0.8, 'width': 2 } },\n { selector: 'edge[edgeType=\"report\"]', style: { 'line-color': '#10b981', 'target-arrow-color': '#10b981', 'opacity': 0.8, 'width': 2 } },\n { selector: 'edge[edgeType=\"message\"]', style: { 'line-color': '#22d3ee', 'target-arrow-color': '#22d3ee', 'line-style': 'dashed', 'line-dash-pattern': [6, 3], 'opacity': 0.7, 'width': 1.5 } },\n { selector: 'edge[edgeType=\"mention\"]', style: { 'line-color': '#ef4444', 'target-arrow-color': '#ef4444', 'line-style': 'dashed', 'line-dash-pattern': [4, 4], 'opacity': 0.9, 'width': 2.5 } },\n ],\n layout: { name: 'preset' },\n minZoom: 0.3,\n maxZoom: 3,\n wheelSensitivity: 0.3,\n });\n\n // Click handling\n this.cy.on('tap', 'node', function (evt) {\n var id = evt.target.id();\n selectedAgentId = id;\n SidebarPanel.show(id);\n });\n\n this.cy.on('tap', function (evt) {\n if (evt.target === GraphRenderer.cy) {\n selectedAgentId = null;\n SidebarPanel.clear();\n }\n });\n\n this.startAnimations();\n },\n\n rebuild: function () {\n if (!this.cy) return;\n this.cy.elements().remove();\n\n var sess = activeSession();\n if (!sess) return;\n\n sess.agents.forEach(function (agent) {\n GraphRenderer.cy.add({\n group: 'nodes',\n data: {\n id: agent.id,\n label: agent.label,\n tier: agent.type,\n status: agent.status,\n department: agent.department,\n },\n });\n });\n\n sess.edges.forEach(function (edge) {\n if (GraphRenderer.cy.getElementById(edge.source).length && GraphRenderer.cy.getElementById(edge.target).length) {\n GraphRenderer.cy.add({\n group: 'edges',\n data: {\n id: edge.id,\n source: edge.source,\n target: edge.target,\n edgeType: edge.edgeType,\n active: edge.active,\n },\n });\n }\n });\n\n this.runLayout();\n },\n\n runLayout: function () {\n if (!this.cy || this.cy.nodes().length === 0) return;\n this.cy.layout({\n name: 'dagre',\n rankDir: 'TB',\n rankSep: 80,\n nodeSep: 40,\n edgeSep: 20,\n animate: true,\n animationDuration: 500,\n animationEasing: 'ease-out',\n padding: 40,\n }).run();\n },\n\n startAnimations: function () {\n var self = this;\n var animate = function () {\n self._dashOffset += 0.5;\n if (self.cy) {\n self.cy.edges('[edgeType=\"delegation\"], [edgeType=\"message\"], [edgeType=\"mention\"]').forEach(function (edge) {\n edge.style('line-dash-offset', -self._dashOffset);\n });\n\n var t = Date.now();\n self.cy.nodes('[status=\"working\"]').forEach(function (node) {\n var glow = 2 + Math.sin(t / 400) * 1;\n node.style('border-width', glow);\n });\n self.cy.nodes('[status=\"in-meeting\"]').forEach(function (node) {\n var op = 0.4 + (Math.sin(t / 1000) + 1) * 0.3;\n node.style('opacity', op);\n });\n self.cy.nodes('[status=\"waiting-for-user\"]').forEach(function (node) {\n var op = 0.5 + (Math.sin(t / 1500) + 1) * 0.25;\n node.style('opacity', op);\n });\n self.cy.nodes('[status=\"spawning-workers\"]').forEach(function (node) {\n var c = Math.sin(t / 600) > 0 ? '#a855f7' : '#22d3ee';\n node.style('border-color', c);\n });\n }\n self._animFrame = requestAnimationFrame(animate);\n };\n self._animFrame = requestAnimationFrame(animate);\n },\n };\n\n // ====================================================================\n // 5. SIDEBAR PANEL\n // ====================================================================\n var SidebarPanel = {\n show: function (agentId) {\n var sess = activeSession();\n if (!sess) { this.clear(); return; }\n var agent = sess.agents.get(agentId);\n if (!agent) { this.clear(); return; }\n\n document.getElementById('sidebar-empty').style.display = 'none';\n var el = document.getElementById('sidebar-content');\n el.style.display = 'block';\n\n // Children\n var children = [];\n sess.agents.forEach(function (a) {\n if (a.parentId === agentId) children.push(a);\n });\n\n // Recent events for this agent\n var recentEvents = sess.eventHistory\n .filter(function (ev) { return ev.agentId === agentId || ev.fromId === agentId || ev.toId === agentId; })\n .slice(-10)\n .reverse();\n\n var tierIcon = agent.type === 'orchestrator' ? '&#x1F3AF;' : agent.type === 'leader' ? '&#x1F451;' : '&#x2699;&#xFE0F;';\n\n el.innerHTML =\n '<div style=\"text-align:center;margin-bottom:8px;\">' +\n '<span style=\"font-size:28px;\">' + tierIcon + '</span>' +\n '<div style=\"font-size:14px;font-weight:700;color:var(--cyan);margin-top:4px;\">' + escHtml(agent.label) + '</div>' +\n '<div style=\"font-size:11px;color:var(--text2);\">' + escHtml(agent.id) + '</div>' +\n '</div>' +\n '<div class=\"detail-row\"><span class=\"label\">Type</span><span class=\"value\">' + agent.type + '</span></div>' +\n '<div class=\"detail-row\"><span class=\"label\">Department</span><span class=\"value\">' + escHtml(agent.department) + '</span></div>' +\n '<div class=\"detail-row\"><span class=\"label\">Status</span><span class=\"value\"><span class=\"status-chip ' + agent.status + '\">' + agent.status + '</span></span></div>' +\n '<div class=\"detail-row\"><span class=\"label\">Cost</span><span class=\"value\">$' + agent.costUsd.toFixed(4) + '</span></div>' +\n '<div class=\"detail-row\"><span class=\"label\">Workers</span><span class=\"value\">' + children.length + '</span></div>' +\n (agent.currentTask\n ? '<h2 style=\"margin-top:12px;\">Current Task</h2><div class=\"task-block\">' + escHtml(agent.currentTask) + '</div>'\n : '') +\n (children.length > 0\n ? '<h2 style=\"margin-top:12px;\">Children</h2><ul class=\"children-list\">' +\n children.map(function (c) { return '<li>' + escHtml(c.label) + ' <span class=\"status-chip ' + c.status + '\" style=\"font-size:10px;\">' + c.status + '</span></li>'; }).join('') +\n '</ul>'\n : '') +\n (recentEvents.length > 0\n ? '<h2 style=\"margin-top:12px;\">Recent Activity</h2><div id=\"task-history\">' +\n recentEvents.map(function (ev) { return '<div class=\"history-item\">' + summarizeEventShort(ev) + '</div>'; }).join('') +\n '</div>'\n : '');\n },\n\n clear: function () {\n document.getElementById('sidebar-empty').style.display = 'block';\n document.getElementById('sidebar-content').style.display = 'none';\n },\n };\n\n // ====================================================================\n // 6. EVENT LOG\n // ====================================================================\n var EventLog = {\n el: null,\n pauseEl: null,\n autoScroll: true,\n maxEntries: 500,\n\n init: function () {\n this.el = document.getElementById('log-entries');\n this.pauseEl = document.getElementById('log-pause');\n var self = this;\n this.el.addEventListener('scroll', function () {\n var atBottom = self.el.scrollHeight - self.el.scrollTop - self.el.clientHeight < 30;\n self.autoScroll = atBottom;\n self.pauseEl.classList.toggle('visible', !atBottom);\n });\n },\n\n append: function (sessionId, displayName, ev) {\n var row = document.createElement('div');\n row.className = 'log-entry';\n\n var now = new Date();\n var ts = pad2(now.getHours()) + ':' + pad2(now.getMinutes()) + ':' + pad2(now.getSeconds());\n\n var kindLabel = '';\n var kindClass = '';\n var message = '';\n\n switch (ev.kind) {\n case 'agent_spawned':\n kindLabel = 'SPAWN'; kindClass = 'spawn';\n message = '<b>' + escHtml(ev.label) + '</b> (' + ev.agentType + ') in ' + escHtml(ev.department);\n break;\n case 'agent_destroyed':\n kindLabel = 'DESTROY'; kindClass = 'destroy';\n message = escHtml(ev.agentId);\n break;\n case 'state_changed':\n kindLabel = 'STATE'; kindClass = 'state';\n message = escHtml(ev.agentId) + ': ' + ev.from + ' &#x2192; ' + ev.to;\n break;\n case 'task_assigned':\n kindLabel = 'TASK'; kindClass = 'task';\n message = escHtml(ev.agentId) + ': ' + escHtml(ev.taskSummary);\n break;\n case 'task_completed':\n kindLabel = ev.result === 'success' ? 'SUCCESS' : 'FAILED';\n kindClass = ev.result === 'success' ? 'done' : 'destroy';\n message = escHtml(ev.agentId);\n break;\n case 'message_sent':\n kindLabel = 'MSG'; kindClass = 'msg';\n message = escHtml(ev.fromId) + ' &#x2192; ' + escHtml(ev.toId) + ': ' + escHtml(ev.summary);\n break;\n case 'mention_created':\n kindLabel = '@MENTION'; kindClass = 'mention';\n message = escHtml(ev.summary) + ' [' + ev.urgency + ']';\n break;\n case 'mention_resolved':\n kindLabel = '@RESOLVED'; kindClass = 'resolved';\n message = escHtml(ev.mentionId) + ': ' + escHtml(ev.decision);\n break;\n case 'cost_update':\n kindLabel = 'COST'; kindClass = 'cost';\n message = 'Total: $' + ev.totalCost.toFixed(4);\n break;\n default:\n kindLabel = 'EVENT'; kindClass = '';\n message = JSON.stringify(ev);\n }\n\n row.innerHTML =\n '<span class=\"log-time\">' + ts + '</span>' +\n '<span class=\"log-session\">' + escHtml(displayName) + '</span>' +\n '<span class=\"log-kind ' + kindClass + '\">' + kindLabel + '</span>' +\n '<span class=\"log-msg\">' + message + '</span>';\n\n this.el.appendChild(row);\n\n while (this.el.children.length > this.maxEntries) {\n this.el.removeChild(this.el.firstChild);\n }\n\n if (this.autoScroll) {\n this.el.scrollTop = this.el.scrollHeight;\n }\n },\n\n appendSystem: function (displayName, message) {\n var row = document.createElement('div');\n row.className = 'log-entry';\n var now = new Date();\n var ts = pad2(now.getHours()) + ':' + pad2(now.getMinutes()) + ':' + pad2(now.getSeconds());\n row.innerHTML =\n '<span class=\"log-time\">' + ts + '</span>' +\n '<span class=\"log-session\">' + escHtml(displayName) + '</span>' +\n '<span class=\"log-kind session\">SESSION</span>' +\n '<span class=\"log-msg\">' + escHtml(message) + '</span>';\n this.el.appendChild(row);\n if (this.autoScroll) this.el.scrollTop = this.el.scrollHeight;\n },\n };\n\n // ====================================================================\n // 7. STATUS BAR\n // ====================================================================\n var StatusBar = {\n update: function () {\n // Session count\n var totalSessions = sessions.size;\n var activeSessions = 0;\n sessions.forEach(function (s) { if (s.isActive) activeSessions++; });\n document.getElementById('badge-sessions').textContent = activeSessions + '/' + totalSessions + ' sessions';\n\n // Agent count + meeting + cost for active tab\n var sess = activeSession();\n if (sess) {\n document.getElementById('badge-agents').textContent = sess.agents.size + ' agent' + (sess.agents.size !== 1 ? 's' : '');\n\n if (sess.meeting) {\n document.getElementById('badge-meeting').textContent = sess.meeting.phase;\n document.getElementById('badge-meeting').className = 'badge amber';\n } else {\n document.getElementById('badge-meeting').textContent = 'No meeting';\n document.getElementById('badge-meeting').className = 'badge purple';\n }\n\n document.getElementById('badge-cost').textContent = '$' + sess.totalCost.toFixed(4);\n } else {\n document.getElementById('badge-agents').textContent = '0 agents';\n document.getElementById('badge-meeting').textContent = 'No meeting';\n document.getElementById('badge-meeting').className = 'badge purple';\n document.getElementById('badge-cost').textContent = '$0.0000';\n }\n },\n };\n\n // ====================================================================\n // HELPERS\n // ====================================================================\n function escHtml(str) {\n if (typeof str !== 'string') return String(str || '');\n return str.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/\"/g, '&quot;');\n }\n\n function pad2(n) {\n return n < 10 ? '0' + n : String(n);\n }\n\n function summarizeEventShort(ev) {\n switch (ev.kind) {\n case 'agent_spawned': return 'Spawned: ' + escHtml(ev.label);\n case 'agent_destroyed': return 'Destroyed';\n case 'state_changed': return ev.from + ' &#x2192; ' + ev.to;\n case 'task_assigned': return 'Task: ' + escHtml(ev.taskSummary);\n case 'task_completed': return 'Completed: ' + ev.result;\n case 'message_sent': return 'Msg to ' + escHtml(ev.toId);\n case 'mention_created': return '@mention: ' + escHtml(ev.summary);\n case 'mention_resolved': return '@resolved: ' + escHtml(ev.decision);\n case 'cost_update': return 'Cost: $' + ev.totalCost.toFixed(4);\n default: return ev.kind;\n }\n }\n\n // ====================================================================\n // BOOT\n // ====================================================================\n document.addEventListener('DOMContentLoaded', function () {\n GraphRenderer.init();\n EventLog.init();\n StatusBar.update();\n ConnectionManager.connect();\n });\n\n})();\n</script>\n</body>\n</html>`;\n}\n","/**\n * StateBridge — manages per-session state and emits 'broadcast' events\n * for the dashboard server to relay to browser WebSocket clients.\n *\n * Supports multiple sessions (one per MCP server instance). Each session\n * tracks its own agent graph independently. Disconnected sessions are kept\n * (grayed-out tab) rather than deleted.\n */\n\nimport { EventEmitter } from 'node:events';\nimport type {\n AgentState,\n EdgeState,\n MeetingState,\n AgentEvent,\n MultiSessionSnapshot,\n SessionDelta,\n} from '../types/dashboard-events.js';\nimport { logger } from '../utils/logger.js';\n\n// ---------------------------------------------------------------------------\n// Per-session state container\n// ---------------------------------------------------------------------------\n\ninterface SessionState {\n projectName: string;\n displayName: string;\n projectPath: string;\n isActive: boolean;\n agents: Map<string, AgentState>;\n edges: EdgeState[];\n meeting: MeetingState | null;\n totalCost: number;\n eventLog: Array<{ timestamp: number; event: AgentEvent }>;\n}\n\n// ---------------------------------------------------------------------------\n// StateBridge\n// ---------------------------------------------------------------------------\n\nexport class StateBridge extends EventEmitter {\n private sessions = new Map<string, SessionState>();\n private debounceTimers = new Map<string, NodeJS.Timeout>();\n private pendingEvents = new Map<string, AgentEvent[]>();\n\n // -----------------------------------------------------------------------\n // Session lifecycle\n // -----------------------------------------------------------------------\n\n registerSession(info: {\n sessionId: string;\n projectPath: string;\n projectName: string;\n }): string {\n const displayName = this.getUniqueDisplayName(info.projectName);\n\n this.sessions.set(info.sessionId, {\n projectName: info.projectName,\n displayName,\n projectPath: info.projectPath,\n isActive: true,\n agents: new Map(),\n edges: [],\n meeting: null,\n totalCost: 0,\n eventLog: [],\n });\n\n logger.info(`Session registered: ${displayName} (${info.sessionId})`);\n\n // Notify browser clients about the new session\n this.emit(\n 'broadcast',\n JSON.stringify({\n type: 'session-registered',\n sessionId: info.sessionId,\n displayName,\n projectPath: info.projectPath,\n }),\n );\n\n return displayName;\n }\n\n unregisterSession(sessionId: string): void {\n const session = this.sessions.get(sessionId);\n if (session) {\n session.isActive = false;\n logger.info(`Session deactivated: ${session.displayName}`);\n\n // Don't delete — keep for display (grayed-out tab)\n this.emit(\n 'broadcast',\n JSON.stringify({\n type: 'session-unregistered',\n sessionId,\n }),\n );\n }\n }\n\n // -----------------------------------------------------------------------\n // Event handling\n // -----------------------------------------------------------------------\n\n handleSessionEvent(sessionId: string, event: AgentEvent): void {\n const session = this.sessions.get(sessionId);\n if (!session) return;\n\n // Apply event to session state\n this.applyEvent(session, event);\n\n // Queue for debounced broadcast\n if (!this.pendingEvents.has(sessionId)) {\n this.pendingEvents.set(sessionId, []);\n }\n this.pendingEvents.get(sessionId)!.push(event);\n\n // Debounce broadcast per session (100ms)\n if (!this.debounceTimers.has(sessionId)) {\n this.debounceTimers.set(\n sessionId,\n setTimeout(() => {\n this.flushEvents(sessionId);\n this.debounceTimers.delete(sessionId);\n }, 100),\n );\n }\n }\n\n // -----------------------------------------------------------------------\n // Snapshot (sent to newly connected browser clients)\n // -----------------------------------------------------------------------\n\n getSnapshot(): MultiSessionSnapshot {\n return {\n type: 'multi-snapshot',\n sessions: Array.from(this.sessions.entries()).map(([sessionId, s]) => ({\n sessionId,\n displayName: s.displayName,\n projectPath: s.projectPath,\n isActive: s.isActive,\n snapshot: {\n agents: Array.from(s.agents.values()),\n edges: [...s.edges],\n meeting: s.meeting,\n totalCost: s.totalCost,\n },\n })),\n };\n }\n\n // -----------------------------------------------------------------------\n // Private — unique display name\n // -----------------------------------------------------------------------\n\n private getUniqueDisplayName(projectName: string): string {\n const existing = Array.from(this.sessions.values()).map(\n (s) => s.displayName,\n );\n if (!existing.includes(projectName)) return projectName;\n let i = 1;\n while (existing.includes(`${projectName} (${i})`)) i++;\n return `${projectName} (${i})`;\n }\n\n // -----------------------------------------------------------------------\n // Private — state mutations (scoped to a session)\n // -----------------------------------------------------------------------\n\n private applyEvent(session: SessionState, event: AgentEvent): void {\n session.eventLog.push({ timestamp: Date.now(), event });\n // Keep log bounded\n if (session.eventLog.length > 500) session.eventLog.shift();\n\n switch (event.kind) {\n case 'agent_spawned': {\n const agent: AgentState = {\n id: event.agentId,\n type: event.agentType,\n label: event.label,\n status: 'idle',\n parentId: event.parentId,\n department: event.department,\n currentTask: null,\n costUsd: 0,\n };\n session.agents.set(event.agentId, agent);\n\n if (event.parentId) {\n session.edges.push({\n id: `edge-${event.parentId}-${event.agentId}`,\n source: event.parentId,\n target: event.agentId,\n edgeType: 'hierarchy',\n active: true,\n label: '',\n });\n }\n break;\n }\n\n case 'agent_destroyed': {\n session.agents.delete(event.agentId);\n session.edges = session.edges.filter(\n (e) => e.source !== event.agentId && e.target !== event.agentId,\n );\n break;\n }\n\n case 'state_changed': {\n const a = session.agents.get(event.agentId);\n if (a) a.status = event.to;\n break;\n }\n\n case 'task_assigned': {\n const a = session.agents.get(event.agentId);\n if (a) {\n a.currentTask = event.taskSummary;\n a.status = 'working';\n }\n break;\n }\n\n case 'task_completed': {\n const a = session.agents.get(event.agentId);\n if (a) {\n a.currentTask = null;\n a.status = event.result === 'success' ? 'completed' : 'failed';\n }\n break;\n }\n\n case 'message_sent': {\n const edgeId = `msg-${event.fromId}-${event.toId}-${Date.now()}`;\n session.edges.push({\n id: edgeId,\n source: event.fromId,\n target: event.toId,\n edgeType: 'message',\n active: true,\n label: event.summary,\n });\n // Remove transient message edges after 5 seconds\n setTimeout(() => {\n session.edges = session.edges.filter((e) => e.id !== edgeId);\n }, 5_000);\n break;\n }\n\n case 'mention_created':\n case 'mention_resolved':\n // Logged but don't mutate the agent graph.\n break;\n\n case 'cost_update': {\n session.totalCost = event.totalCost;\n break;\n }\n }\n }\n\n // -----------------------------------------------------------------------\n // Private — flush debounced events\n // -----------------------------------------------------------------------\n\n private flushEvents(sessionId: string): void {\n const events = this.pendingEvents.get(sessionId);\n const session = this.sessions.get(sessionId);\n if (!events || !session || events.length === 0) return;\n\n const delta: SessionDelta = {\n type: 'session-delta',\n sessionId,\n displayName: session.displayName,\n timestamp: Date.now(),\n events: [...events],\n };\n\n this.emit('broadcast', JSON.stringify(delta));\n this.pendingEvents.set(sessionId, []);\n }\n}\n","import WebSocket from 'ws';\nimport type { AgentEvent, RegisterMessage, SessionEventMessage, UnregisterMessage } from '../types/dashboard-events.js';\nimport { eventBus } from '../orchestrator/event-bus.js';\nimport { logger } from '../utils/logger.js';\n\nexport class DashboardClient {\n private ws: WebSocket | null = null;\n private sessionId: string;\n private projectName: string;\n private projectPath: string;\n\n constructor(sessionId: string, projectName: string, projectPath: string) {\n this.sessionId = sessionId;\n this.projectName = projectName;\n this.projectPath = projectPath;\n }\n\n connect(port: number): void {\n this.ws = new WebSocket(`ws://127.0.0.1:${port}`);\n\n this.ws.on('open', () => {\n logger.info(`Connected to dashboard as client (session: ${this.sessionId})`);\n // Register this session\n const msg: RegisterMessage = {\n type: 'register',\n sessionId: this.sessionId,\n projectPath: this.projectPath,\n projectName: this.projectName,\n };\n this.ws!.send(JSON.stringify(msg));\n\n // Forward local events to the dashboard server\n eventBus.on('agent_event', (event: AgentEvent) => {\n if (this.ws?.readyState === WebSocket.OPEN) {\n const sessionMsg: SessionEventMessage = {\n type: 'session-event',\n sessionId: this.sessionId,\n event,\n };\n this.ws.send(JSON.stringify(sessionMsg));\n }\n });\n });\n\n this.ws.on('error', (err) => {\n logger.warn(`Dashboard client error: ${err.message}`);\n });\n\n this.ws.on('close', () => {\n logger.info('Dashboard client disconnected');\n });\n }\n\n disconnect(): void {\n if (this.ws && this.ws.readyState === WebSocket.OPEN) {\n const msg: UnregisterMessage = {\n type: 'unregister',\n sessionId: this.sessionId,\n };\n this.ws.send(JSON.stringify(msg));\n this.ws.close();\n }\n this.ws = null;\n }\n}\n"],"mappings":"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AAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;A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","names":["uuidv4","uuidv4","uuidv4","uuidv4","uuidv4","uuidv4","uuidv4","uuidv4","uuidv4","z","z","result","z","z","z","uuidv4","DEPARTMENT_KEYWORDS","uuidv4","z","z","z","z","z","z","z","getDb","z","z","z","z","z","z","z","readFileSync","existsSync","join","join","join","existsSync","readFileSync","mkdirSync","writeFileSync","join","join","mkdirSync","writeFileSync","readFileSync","writeFileSync","join","join","writeFileSync","z","z","z","z","z","WebSocket","EventEmitter","EventEmitter","WebSocket"]}