import type { AgentAdapter, AgentType } from './types.js'; import type { AgentConfig, TaskAssignment, InputResponse } from '../types/index.js'; import type { AgentWebSocketClient } from '../daemon/ws-client.js'; export interface LearnedRule { content: string; confidence: number; sourceCount: number; createdAt: string; } export interface AgentMetrics { taskCount: number; successCount: number; failCount: number; totalDurationMs: number; avgDurationMs: number; reflectionCount: number; reflectionSkipCount: number; memoryCount: number; patternsLearnedCount: number; rulesCount: number; lastTaskAt: string | null; lastReflectionAt: string | null; lastPatternAt: string | null; latestLearnedRule: string | null; lastScore: number | null; scoreTrend: string | null; upSince: string; } export declare class ClaudeCodeAdapter implements AgentAdapter { readonly type: AgentType; readonly displayName = "Claude Code"; private readonly agentConfig; private taskCount; private static readonly PATTERN_CHECK_INTERVAL; private metricsMap; private learnedRulesMap; private agentFolderMap; /** Returns metrics for a specific agent by ID (safe for parallel execution). */ getMetricsForAgent(agentId: string): AgentMetrics; constructor(config: AgentConfig); /** Resolve CLAUDE.md path — check root first, then .claude/ subfolder. */ static resolveClaudeMdPath(folder: string): string; /** Get all per-agent metrics for heartbeat. */ getMetrics(): Record; /** Register an agent folder path for rules parsing (called from daemon). */ registerAgentFolder(agentId: string, folderPath: string): void; /** Get folder path for an agent by ID (returns undefined if not registered). */ getAgentFolder(agentId: string): string | undefined; /** Seed memoryCount from Mem0 for all registered agents (called once on daemon startup). */ seedMemoryCounts(): Promise; checkHealth(): Promise<{ ok: boolean; message: string; }>; handleTask(task: TaskAssignment, ws: AgentWebSocketClient, pendingInputResolvers: Map void>, signal?: AbortSignal, pendingPermissionResolvers?: Map void>): Promise; /** * Run post-task self-reflection via Mem0. * Agent reviews what it did and stores lessons learned. */ runReflection(task: TaskAssignment, resultSummary: string, status: 'done' | 'failed', cwd: string, conversation?: string[]): Promise; /** * Store user rating feedback into Mem0. */ storeRatingMemory(data: { taskTitle: string; taskDescription: string; score: number; comment?: string; cwd: string; }): Promise; /** * Self-Improvement: detect patterns from Mem0 and update CLAUDE.md. * Runs every N tasks to evolve the agent's permanent knowledge. */ /** Extract key phrases (3+ word sequences) from a rule for similarity matching. */ private static extractKeyPhrases; /** Check if two rules are semantically similar (>40% key phrase overlap). */ private static isSimilarRule; /** Cosine similarity between two equal-length embedding vectors. */ private static cosine; /** Path to the per-agent self-improvement score log (one JSON line per scored task). */ private static scoresFile; /** * Derive a 0-10 quality score for a completed task — the signal the self-improvement * loop optimizes against (SIA-style: a measurable score gates whether changes help). * Prefers an explicit rubric score the agent emits ("[SCORE: N]" / "QUALITY_SCORE: N"); * otherwise falls back to a deterministic proxy from status + result keywords. */ static deriveScore(status: 'done' | 'failed', resultSummary: string): number; /** Append one score record to the agent's score log; update in-memory metrics. */ recordRunScore(cwd: string, agentId: string, score: number, note: string): void; /** Read the last N scores from the agent's score log (oldest→newest). */ static readRecentScores(cwd: string, n: number): number[]; /** * Classify the recent score trend. Compares the latest score to the mean of the * prior window. Needs >=3 points; otherwise 'insufficient'. */ static computeScoreTrend(scores: number[]): 'up' | 'flat' | 'down' | 'insufficient'; /** * Enforce the Learned Rules cap on EVERY task, independent of the pattern-check * interval. The daemon only ADDS rules every Nth task, but agents also append * rules THEMSELVES mid-session (their CLAUDE.md invites it) — pm hit 50 and aso * 52 rules while the interval-gated prune waited its turn. Cheap: parse + trim * lowest-confidence over cap. */ private static pruneRulesToCap; runSelfImprovement(cwd: string, agentId: string): Promise; /** * Parse "## Learned Rules" section from CLAUDE.md and store in learnedRulesMap. * Rule format: `- Rule text (confidence: 0.7)` */ private parseLearnedRules; /** Track task completion metrics (public for daemon resume path). */ trackMetricsPublic(status: 'done' | 'failed', durationMs: number, agentId: string): void; /** Track task completion metrics. */ private trackMetrics; dispose(): Promise; }