harness-evolve 1.0.0
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/LICENSE +21 -0
- package/README.md +254 -0
- package/dist/cli.js +1685 -0
- package/dist/cli.js.map +1 -0
- package/dist/delivery/run-evolve.d.ts +2 -0
- package/dist/delivery/run-evolve.js +2069 -0
- package/dist/delivery/run-evolve.js.map +1 -0
- package/dist/hooks/permission-request.d.ts +8 -0
- package/dist/hooks/permission-request.js +405 -0
- package/dist/hooks/permission-request.js.map +1 -0
- package/dist/hooks/post-tool-use-failure.d.ts +9 -0
- package/dist/hooks/post-tool-use-failure.js +437 -0
- package/dist/hooks/post-tool-use-failure.js.map +1 -0
- package/dist/hooks/post-tool-use.d.ts +9 -0
- package/dist/hooks/post-tool-use.js +441 -0
- package/dist/hooks/post-tool-use.js.map +1 -0
- package/dist/hooks/pre-tool-use.d.ts +8 -0
- package/dist/hooks/pre-tool-use.js +434 -0
- package/dist/hooks/pre-tool-use.js.map +1 -0
- package/dist/hooks/stop.d.ts +8 -0
- package/dist/hooks/stop.js +1609 -0
- package/dist/hooks/stop.js.map +1 -0
- package/dist/hooks/user-prompt-submit.d.ts +8 -0
- package/dist/hooks/user-prompt-submit.js +442 -0
- package/dist/hooks/user-prompt-submit.js.map +1 -0
- package/dist/index.d.ts +1029 -0
- package/dist/index.js +3131 -0
- package/dist/index.js.map +1 -0
- package/package.json +104 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/schemas/hook-input.ts","../../src/storage/counter.ts","../../src/schemas/counter.ts","../../src/storage/dirs.ts","../../src/storage/config.ts","../../src/schemas/config.ts","../../src/analysis/jsonl-reader.ts","../../src/analysis/schemas.ts","../../src/schemas/log-entry.ts","../../src/analysis/pre-processor.ts","../../src/analysis/environment-scanner.ts","../../src/analysis/classifiers/repeated-prompts.ts","../../src/analysis/classifiers/long-prompts.ts","../../src/analysis/classifiers/permission-patterns.ts","../../src/analysis/classifiers/code-corrections.ts","../../src/analysis/classifiers/personal-info.ts","../../src/analysis/classifiers/config-drift.ts","../../src/analysis/classifiers/ecosystem-adapter.ts","../../src/analysis/experience-level.ts","../../src/analysis/classifiers/onboarding.ts","../../src/analysis/classifiers/index.ts","../../src/schemas/recommendation.ts","../../src/analysis/analyzer.ts","../../src/analysis/outcome-tracker.ts","../../src/delivery/state.ts","../../src/schemas/delivery.ts","../../src/schemas/onboarding.ts","../../src/analysis/trigger.ts","../../src/hooks/shared.ts","../../src/hooks/stop.ts"],"sourcesContent":["import { z } from 'zod/v4';\n\n// Common fields present in ALL Claude Code hook events\nexport const hookCommonSchema = z.object({\n session_id: z.string(),\n transcript_path: z.string(),\n cwd: z.string(),\n permission_mode: z.string(),\n});\nexport type HookCommon = z.infer<typeof hookCommonSchema>;\n\n// UserPromptSubmit: fires when user submits a prompt\nexport const userPromptSubmitInputSchema = hookCommonSchema.extend({\n hook_event_name: z.literal('UserPromptSubmit'),\n prompt: z.string(),\n});\nexport type UserPromptSubmitInput = z.infer<typeof userPromptSubmitInputSchema>;\n\n// PreToolUse: fires before a tool is invoked\nexport const preToolUseInputSchema = hookCommonSchema.extend({\n hook_event_name: z.literal('PreToolUse'),\n tool_name: z.string(),\n tool_input: z.record(z.string(), z.unknown()),\n tool_use_id: z.string(),\n});\nexport type PreToolUseInput = z.infer<typeof preToolUseInputSchema>;\n\n// PostToolUse: fires after a tool completes successfully\nexport const postToolUseInputSchema = hookCommonSchema.extend({\n hook_event_name: z.literal('PostToolUse'),\n tool_name: z.string(),\n tool_input: z.record(z.string(), z.unknown()),\n tool_response: z.unknown().optional(),\n tool_use_id: z.string(),\n});\nexport type PostToolUseInput = z.infer<typeof postToolUseInputSchema>;\n\n// PostToolUseFailure: fires after a tool execution fails\nexport const postToolUseFailureInputSchema = hookCommonSchema.extend({\n hook_event_name: z.literal('PostToolUseFailure'),\n tool_name: z.string(),\n tool_input: z.record(z.string(), z.unknown()),\n tool_use_id: z.string(),\n error: z.string().optional(),\n is_interrupt: z.boolean().optional(),\n});\nexport type PostToolUseFailureInput = z.infer<typeof postToolUseFailureInputSchema>;\n\n// PermissionRequest: fires before user sees permission dialog\nexport const permissionRequestInputSchema = hookCommonSchema.extend({\n hook_event_name: z.literal('PermissionRequest'),\n tool_name: z.string(),\n tool_input: z.record(z.string(), z.unknown()),\n permission_suggestions: z.array(z.unknown()).optional(),\n});\nexport type PermissionRequestInput = z.infer<typeof permissionRequestInputSchema>;\n\n// Stop: fires after Claude Code completes a response\nexport const stopInputSchema = hookCommonSchema.extend({\n hook_event_name: z.literal('Stop'),\n stop_hook_active: z.boolean(),\n last_assistant_message: z.string().optional(),\n});\nexport type StopInput = z.infer<typeof stopInputSchema>;\n","import { readFile } from 'node:fs/promises';\nimport { lock } from 'proper-lockfile';\nimport writeFileAtomic from 'write-file-atomic';\nimport { counterSchema, type Counter } from '../schemas/counter.js';\nimport { paths, ensureInit } from './dirs.js';\n\n/**\n * Read the current counter state from disk.\n * Returns defaults (total=0, session={}) if no counter file exists.\n */\nexport async function readCounter(): Promise<Counter> {\n await ensureInit();\n try {\n const raw = await readFile(paths.counter, 'utf-8');\n return counterSchema.parse(JSON.parse(raw));\n } catch {\n // File doesn't exist or invalid -- return defaults\n return {\n total: 0,\n session: {},\n last_updated: new Date().toISOString(),\n };\n }\n}\n\n/**\n * Atomically increment the interaction counter with cross-process safety.\n *\n * Uses proper-lockfile (mkdir-based, macOS-safe) for cross-process locking\n * and write-file-atomic for crash-safe writes inside the lock.\n *\n * Pattern: ensure-file -> lock -> read -> increment -> atomic-write -> unlock\n */\nexport async function incrementCounter(sessionId: string): Promise<number> {\n await ensureInit();\n\n // Ensure counter file exists before locking (proper-lockfile requires existing file)\n try {\n await readFile(paths.counter, 'utf-8');\n } catch {\n const initial: Counter = {\n total: 0,\n session: {},\n last_updated: new Date().toISOString(),\n };\n await writeFileAtomic(paths.counter, JSON.stringify(initial, null, 2));\n }\n\n const release = await lock(paths.counter, {\n retries: { retries: 50, minTimeout: 20, maxTimeout: 1000, randomize: true },\n stale: 10000, // Consider lock stale after 10 seconds\n });\n\n try {\n const raw = await readFile(paths.counter, 'utf-8');\n const data = counterSchema.parse(JSON.parse(raw));\n data.total += 1;\n data.session[sessionId] = (data.session[sessionId] ?? 0) + 1;\n data.last_updated = new Date().toISOString();\n await writeFileAtomic(paths.counter, JSON.stringify(data, null, 2));\n return data.total;\n } finally {\n await release();\n }\n}\n\n/**\n * Reset the counter to zero. Used for testing and post-analysis reset.\n */\nexport async function resetCounter(): Promise<void> {\n await ensureInit();\n const data: Counter = {\n total: 0,\n session: {},\n last_updated: new Date().toISOString(),\n };\n await writeFileAtomic(paths.counter, JSON.stringify(data, null, 2));\n}\n","import { z } from 'zod/v4';\n\nexport const counterSchema = z.object({\n total: z.number().default(0),\n session: z.record(z.string(), z.number()).default({}),\n last_analysis: z.iso.datetime().optional(),\n last_updated: z.iso.datetime(),\n});\nexport type Counter = z.infer<typeof counterSchema>;\n","import { mkdir } from 'node:fs/promises';\nimport { join } from 'node:path';\n\nconst BASE_DIR = join(process.env.HOME ?? '', '.harness-evolve');\n\nexport const paths = {\n base: BASE_DIR,\n logs: {\n prompts: join(BASE_DIR, 'logs', 'prompts'),\n tools: join(BASE_DIR, 'logs', 'tools'),\n permissions: join(BASE_DIR, 'logs', 'permissions'),\n sessions: join(BASE_DIR, 'logs', 'sessions'),\n },\n analysis: join(BASE_DIR, 'analysis'),\n analysisPreProcessed: join(BASE_DIR, 'analysis', 'pre-processed'),\n summary: join(BASE_DIR, 'analysis', 'pre-processed', 'summary.json'),\n environmentSnapshot: join(BASE_DIR, 'analysis', 'environment-snapshot.json'),\n analysisResult: join(BASE_DIR, 'analysis', 'analysis-result.json'),\n pending: join(BASE_DIR, 'pending'),\n config: join(BASE_DIR, 'config.json'),\n counter: join(BASE_DIR, 'counter.json'),\n recommendations: join(BASE_DIR, 'recommendations.md'),\n recommendationState: join(BASE_DIR, 'analysis', 'recommendation-state.json'),\n recommendationArchive: join(BASE_DIR, 'analysis', 'recommendations-archive'),\n notificationFlag: join(BASE_DIR, 'analysis', 'has-pending-notifications'),\n autoApplyLog: join(BASE_DIR, 'analysis', 'auto-apply-log.jsonl'),\n outcomeHistory: join(BASE_DIR, 'analysis', 'outcome-history.jsonl'),\n} as const;\n\nlet initialized = false;\n\nexport async function ensureInit(): Promise<void> {\n if (initialized) return;\n await mkdir(paths.logs.prompts, { recursive: true });\n await mkdir(paths.logs.tools, { recursive: true });\n await mkdir(paths.logs.permissions, { recursive: true });\n await mkdir(paths.logs.sessions, { recursive: true });\n await mkdir(paths.analysis, { recursive: true });\n await mkdir(paths.analysisPreProcessed, { recursive: true });\n await mkdir(paths.pending, { recursive: true });\n await mkdir(paths.recommendationArchive, { recursive: true });\n initialized = true;\n}\n\n// For testing: reset the initialized flag\nexport function resetInit(): void {\n initialized = false;\n}\n","import { readFile } from 'node:fs/promises';\nimport writeFileAtomic from 'write-file-atomic';\nimport { configSchema, type Config } from '../schemas/config.js';\nimport { paths } from './dirs.js';\n\nexport async function loadConfig(): Promise<Config> {\n try {\n const raw = await readFile(paths.config, 'utf-8');\n return configSchema.parse(JSON.parse(raw));\n } catch {\n // File doesn't exist, is invalid JSON, or fails strict validation\n const defaults = configSchema.parse({});\n await writeFileAtomic(paths.config, JSON.stringify(defaults, null, 2));\n return defaults;\n }\n}\n","import { z } from 'zod/v4';\n\nexport const configSchema = z.object({\n version: z.number().default(1),\n analysis: z.object({\n threshold: z.number().min(1).default(50),\n enabled: z.boolean().default(true),\n classifierThresholds: z.record(z.string(), z.number()).default({}),\n }).default({ threshold: 50, enabled: true, classifierThresholds: {} }),\n hooks: z.object({\n capturePrompts: z.boolean().default(true),\n captureTools: z.boolean().default(true),\n capturePermissions: z.boolean().default(true),\n captureSessions: z.boolean().default(true),\n }).default({\n capturePrompts: true,\n captureTools: true,\n capturePermissions: true,\n captureSessions: true,\n }),\n scrubbing: z.object({\n enabled: z.boolean().default(true),\n highEntropyDetection: z.boolean().default(false),\n customPatterns: z.array(z.object({\n name: z.string(),\n regex: z.string(),\n replacement: z.string(),\n })).default([]),\n }).default({\n enabled: true,\n highEntropyDetection: false,\n customPatterns: [],\n }),\n delivery: z.object({\n stdoutInjection: z.boolean().default(true),\n maxTokens: z.number().default(200),\n fullAuto: z.boolean().default(false),\n maxRecommendationsInFile: z.number().default(20),\n archiveAfterDays: z.number().default(7),\n }).default({\n stdoutInjection: true,\n maxTokens: 200,\n fullAuto: false,\n maxRecommendationsInFile: 20,\n archiveAfterDays: 7,\n }),\n}).strict();\n\nexport type Config = z.infer<typeof configSchema>;\n","// Streaming JSONL reader with date-range filtering and schema validation.\n// Reads daily-rotated .jsonl log files (YYYY-MM-DD.jsonl) and returns\n// validated, typed entries. Malformed or schema-invalid lines are silently\n// skipped to ensure robustness against partial writes or corruption.\n\nimport { createReadStream } from 'node:fs';\nimport { readdir } from 'node:fs/promises';\nimport { createInterface } from 'node:readline';\nimport { join } from 'node:path';\nimport type { z } from 'zod/v4';\n\n/**\n * Format a Date as YYYY-MM-DD for filename comparison.\n */\nfunction formatDate(d: Date): string {\n return d.toISOString().slice(0, 10);\n}\n\n/**\n * Read and parse all JSONL entries from a log directory, optionally\n * filtered by date range. Files are read in chronological order\n * (sorted by YYYY-MM-DD filename).\n *\n * @param logDir - Directory containing YYYY-MM-DD.jsonl files\n * @param schema - Zod schema for parsing and type inference\n * @param options - Optional date range filter (inclusive boundaries)\n * @returns Array of validated, typed entries\n */\nexport async function readLogEntries<T>(\n logDir: string,\n schema: z.ZodType<T>,\n options?: { since?: Date; until?: Date },\n): Promise<T[]> {\n let fileNames: string[];\n try {\n fileNames = await readdir(logDir);\n } catch {\n // Directory does not exist or is unreadable\n return [];\n }\n\n // Keep only .jsonl files\n let jsonlFiles = fileNames.filter((f) => f.endsWith('.jsonl'));\n\n // Apply date range filtering based on filename (YYYY-MM-DD.jsonl)\n const sinceStr = options?.since ? formatDate(options.since) : undefined;\n const untilStr = options?.until ? formatDate(options.until) : undefined;\n\n if (sinceStr || untilStr) {\n jsonlFiles = jsonlFiles.filter((f) => {\n const dateStr = f.replace('.jsonl', '');\n if (sinceStr && dateStr < sinceStr) return false;\n if (untilStr && dateStr > untilStr) return false;\n return true;\n });\n }\n\n // Sort alphabetically for chronological order (YYYY-MM-DD sorts lexically)\n jsonlFiles.sort();\n\n const entries: T[] = [];\n\n for (const file of jsonlFiles) {\n const filePath = join(logDir, file);\n const rl = createInterface({\n input: createReadStream(filePath, 'utf-8'),\n crlfDelay: Infinity,\n });\n\n for await (const line of rl) {\n if (!line.trim()) continue;\n try {\n const parsed = schema.parse(JSON.parse(line));\n entries.push(parsed);\n } catch {\n // Silently skip malformed JSON or schema validation failures\n }\n }\n }\n\n return entries;\n}\n","// Output schemas for analysis results.\n// Defines the shape of summary.json and environment-snapshot.json.\n\nimport { z } from 'zod/v4';\n\n// Summary schema: aggregated usage statistics from log pre-processing\nexport const summarySchema = z.object({\n generated_at: z.iso.datetime(),\n period: z.object({\n since: z.string(), // YYYY-MM-DD\n until: z.string(), // YYYY-MM-DD\n days: z.number(),\n }),\n stats: z.object({\n total_prompts: z.number(),\n total_tool_uses: z.number(),\n total_permissions: z.number(),\n unique_sessions: z.number(),\n }),\n top_repeated_prompts: z\n .array(\n z.object({\n prompt: z.string(),\n count: z.number(),\n sessions: z.number(),\n }),\n )\n .max(20),\n tool_frequency: z.array(\n z.object({\n tool_name: z.string(),\n count: z.number(),\n avg_duration_ms: z.number().optional(),\n }),\n ),\n permission_patterns: z.array(\n z.object({\n tool_name: z.string(),\n count: z.number(),\n sessions: z.number(),\n }),\n ),\n long_prompts: z\n .array(\n z.object({\n prompt_preview: z.string(),\n length: z.number(),\n count: z.number(),\n }),\n )\n .max(10),\n});\nexport type Summary = z.infer<typeof summarySchema>;\n\n// Environment snapshot schema: discovered tools, settings, and ecosystems\nexport const environmentSnapshotSchema = z.object({\n generated_at: z.iso.datetime(),\n claude_code: z.object({\n version: z.string(),\n version_known: z.boolean(),\n compatible: z.boolean(),\n }),\n settings: z.object({\n user: z.unknown().nullable(),\n project: z.unknown().nullable(),\n local: z.unknown().nullable(),\n }),\n installed_tools: z.object({\n plugins: z.array(\n z.object({\n name: z.string(),\n marketplace: z.string(),\n enabled: z.boolean(),\n scope: z.string(),\n capabilities: z.array(z.string()),\n }),\n ),\n skills: z.array(\n z.object({\n name: z.string(),\n scope: z.enum(['user', 'project']),\n }),\n ),\n rules: z.array(\n z.object({\n name: z.string(),\n scope: z.enum(['user', 'project']),\n }),\n ),\n hooks: z.array(\n z.object({\n event: z.string(),\n scope: z.enum(['user', 'project', 'local']),\n type: z.string(),\n }),\n ),\n claude_md: z.array(\n z.object({\n path: z.string(),\n exists: z.boolean(),\n }),\n ),\n }),\n detected_ecosystems: z.array(z.string()),\n});\nexport type EnvironmentSnapshot = z.infer<typeof environmentSnapshotSchema>;\n","import { z } from 'zod/v4';\n\nexport const promptEntrySchema = z.object({\n timestamp: z.iso.datetime(),\n session_id: z.string(),\n cwd: z.string(),\n prompt: z.string(),\n prompt_length: z.number(),\n transcript_path: z.string().optional(),\n});\nexport type PromptEntry = z.infer<typeof promptEntrySchema>;\n\nexport const toolEntrySchema = z.object({\n timestamp: z.iso.datetime(),\n session_id: z.string(),\n event: z.enum(['pre', 'post', 'failure']),\n tool_name: z.string(),\n input_summary: z.string().optional(),\n duration_ms: z.number().optional(),\n success: z.boolean().optional(),\n});\nexport type ToolEntry = z.infer<typeof toolEntrySchema>;\n\nexport const permissionEntrySchema = z.object({\n timestamp: z.iso.datetime(),\n session_id: z.string(),\n tool_name: z.string(),\n decision: z.enum(['approved', 'denied', 'unknown']),\n});\nexport type PermissionEntry = z.infer<typeof permissionEntrySchema>;\n\nexport const sessionEntrySchema = z.object({\n timestamp: z.iso.datetime(),\n session_id: z.string(),\n event: z.enum(['start', 'end']),\n cwd: z.string().optional(),\n});\nexport type SessionEntry = z.infer<typeof sessionEntrySchema>;\n","// Pre-processing pipeline: reads accumulated JSONL logs, computes frequency\n// counts with cross-session tracking, extracts top-N patterns, and writes\n// a compact summary.json under 50KB for the analysis agent's context window.\n\nimport { readLogEntries } from './jsonl-reader.js';\nimport { summarySchema, type Summary } from './schemas.js';\nimport {\n promptEntrySchema,\n toolEntrySchema,\n permissionEntrySchema,\n} from '../schemas/log-entry.js';\nimport type { PromptEntry, ToolEntry } from '../schemas/log-entry.js';\nimport { paths, ensureInit } from '../storage/dirs.js';\nimport writeFileAtomic from 'write-file-atomic';\n\nconst PROMPT_TRUNCATE_LEN = 100;\nconst LONG_PROMPT_THRESHOLD = 200; // word count\nconst DEFAULT_TOP_N = 20;\nconst DEFAULT_DAYS = 30;\nconst MAX_LONG_PROMPTS = 10;\n\n/**\n * Normalize a prompt string for deduplication:\n * trim, lowercase, collapse all whitespace to a single space.\n */\nfunction normalizePrompt(prompt: string): string {\n return prompt.trim().toLowerCase().replace(/\\s+/g, ' ');\n}\n\n/**\n * Format a Date as YYYY-MM-DD.\n */\nfunction formatDate(d: Date): string {\n return d.toISOString().slice(0, 10);\n}\n\n/**\n * Count items with cross-session tracking.\n * Returns a Map keyed by the normalized identifier with count and unique sessions.\n */\nfunction countWithSessions(\n items: Array<{ key: string; session: string }>,\n): Map<string, { count: number; sessions: Set<string> }> {\n const map = new Map<string, { count: number; sessions: Set<string> }>();\n for (const { key, session } of items) {\n const existing = map.get(key);\n if (existing) {\n existing.count += 1;\n existing.sessions.add(session);\n } else {\n map.set(key, { count: 1, sessions: new Set([session]) });\n }\n }\n return map;\n}\n\n/**\n * Compute tool frequency with average duration from 'post' events.\n */\nfunction computeToolFrequency(\n tools: ToolEntry[],\n): Summary['tool_frequency'] {\n const map = new Map<string, { count: number; durations: number[] }>();\n for (const entry of tools) {\n const existing = map.get(entry.tool_name);\n if (existing) {\n existing.count += 1;\n if (entry.event === 'post' && entry.duration_ms != null) {\n existing.durations.push(entry.duration_ms);\n }\n } else {\n const durations: number[] = [];\n if (entry.event === 'post' && entry.duration_ms != null) {\n durations.push(entry.duration_ms);\n }\n map.set(entry.tool_name, { count: 1, durations });\n }\n }\n\n return Array.from(map.entries())\n .map(([tool_name, { count, durations }]) => ({\n tool_name,\n count,\n avg_duration_ms:\n durations.length > 0\n ? Math.round(\n durations.reduce((sum, d) => sum + d, 0) / durations.length,\n )\n : undefined,\n }))\n .sort((a, b) => b.count - a.count);\n}\n\n/**\n * Detect long prompts (over LONG_PROMPT_THRESHOLD words).\n * Groups by normalized text, counts occurrences, returns top MAX_LONG_PROMPTS.\n */\nfunction detectLongPrompts(prompts: PromptEntry[]): Summary['long_prompts'] {\n const map = new Map<string, { length: number; count: number }>();\n for (const entry of prompts) {\n const words = entry.prompt.trim().split(/\\s+/);\n if (words.length <= LONG_PROMPT_THRESHOLD) continue;\n const key = normalizePrompt(entry.prompt);\n const existing = map.get(key);\n if (existing) {\n existing.count += 1;\n } else {\n map.set(key, { length: words.length, count: 1 });\n }\n }\n\n return Array.from(map.entries())\n .sort((a, b) => b[1].count - a[1].count)\n .slice(0, MAX_LONG_PROMPTS)\n .map(([normalized, { length, count }]) => ({\n prompt_preview: normalized.slice(0, PROMPT_TRUNCATE_LEN),\n length,\n count,\n }));\n}\n\n/**\n * Pre-process accumulated JSONL logs and produce a compact summary.\n *\n * Reads prompt, tool, and permission logs within the specified date range,\n * computes frequency counts with cross-session aggregation, and writes\n * the result atomically to paths.summary.\n *\n * @param options.since - Start of date range (defaults to 30 days ago)\n * @param options.until - End of date range (defaults to now)\n * @param options.topN - Max entries in top_repeated_prompts (defaults to 20)\n * @returns The validated Summary object\n */\nexport async function preProcess(options?: {\n since?: Date;\n until?: Date;\n topN?: number;\n}): Promise<Summary> {\n const until = options?.until ?? new Date();\n const since =\n options?.since ?? new Date(until.getTime() - DEFAULT_DAYS * 86_400_000);\n const topN = options?.topN ?? DEFAULT_TOP_N;\n\n // Read all log entries within the date range\n const [prompts, tools, permissions] = await Promise.all([\n readLogEntries(paths.logs.prompts, promptEntrySchema, { since, until }),\n readLogEntries(paths.logs.tools, toolEntrySchema, { since, until }),\n readLogEntries(paths.logs.permissions, permissionEntrySchema, {\n since,\n until,\n }),\n ]);\n\n // Unique sessions across all entry types\n const sessionSet = new Set<string>();\n for (const p of prompts) sessionSet.add(p.session_id);\n for (const t of tools) sessionSet.add(t.session_id);\n for (const perm of permissions) sessionSet.add(perm.session_id);\n\n // Prompt frequency with cross-session tracking\n const promptCounts = countWithSessions(\n prompts.map((p) => ({\n key: normalizePrompt(p.prompt),\n session: p.session_id,\n })),\n );\n\n const topRepeatedPrompts = Array.from(promptCounts.entries())\n .sort((a, b) => b[1].count - a[1].count)\n .slice(0, topN)\n .map(([key, { count, sessions }]) => ({\n prompt: key.slice(0, PROMPT_TRUNCATE_LEN),\n count,\n sessions: sessions.size,\n }));\n\n // Tool frequency with average duration\n const toolFrequency = computeToolFrequency(tools);\n\n // Permission patterns with cross-session tracking\n const permissionCounts = countWithSessions(\n permissions.map((p) => ({\n key: p.tool_name,\n session: p.session_id,\n })),\n );\n\n const permissionPatterns = Array.from(permissionCounts.entries())\n .sort((a, b) => b[1].count - a[1].count)\n .map(([tool_name, { count, sessions }]) => ({\n tool_name,\n count,\n sessions: sessions.size,\n }));\n\n // Long prompt detection\n const longPrompts = detectLongPrompts(prompts);\n\n // Construct and validate summary\n const summary: Summary = summarySchema.parse({\n generated_at: new Date().toISOString(),\n period: {\n since: formatDate(since),\n until: formatDate(until),\n days: DEFAULT_DAYS,\n },\n stats: {\n total_prompts: prompts.length,\n total_tool_uses: tools.length,\n total_permissions: permissions.length,\n unique_sessions: sessionSet.size,\n },\n top_repeated_prompts: topRepeatedPrompts,\n tool_frequency: toolFrequency,\n permission_patterns: permissionPatterns,\n long_prompts: longPrompts,\n });\n\n // Write atomically to disk\n await ensureInit();\n await writeFileAtomic(paths.summary, JSON.stringify(summary));\n\n return summary;\n}\n","// Environment scanner: discovers installed Claude Code tools via filesystem\n// scanning, reads settings at all scopes, detects Claude Code version, and\n// identifies ecosystem presence (GSD, Cog, etc.).\n\nimport { readdir, readFile, access } from 'node:fs/promises';\nimport { execFileSync } from 'node:child_process';\nimport { join } from 'node:path';\nimport { constants } from 'node:fs';\nimport writeFileAtomic from 'write-file-atomic';\nimport {\n environmentSnapshotSchema,\n type EnvironmentSnapshot,\n} from './schemas.js';\nimport { paths, ensureInit } from '../storage/dirs.js';\n\n// Version compatibility range -- tested and verified\nconst KNOWN_COMPATIBLE_MIN = '2.1.0';\nconst KNOWN_COMPATIBLE_MAX = '2.1.99';\n\n/**\n * Scan the user's environment to discover installed Claude Code tools,\n * settings, version info, and ecosystem presence. Writes the snapshot\n * atomically to paths.environmentSnapshot.\n *\n * @param cwd - Current working directory (project root)\n * @param home - User home directory (defaults to process.env.HOME)\n * @returns Validated EnvironmentSnapshot\n */\nexport async function scanEnvironment(\n cwd: string,\n home?: string,\n): Promise<EnvironmentSnapshot> {\n const homeDir = home ?? process.env.HOME ?? '';\n\n // Read all 3 settings files in parallel\n const [userSettings, projectSettings, localSettings] = await Promise.all([\n readSettingsSafe(join(homeDir, '.claude', 'settings.json')),\n readSettingsSafe(join(cwd, '.claude', 'settings.json')),\n readSettingsSafe(join(cwd, '.claude', 'settings.local.json')),\n ]);\n\n // Extract enabledPlugins from user settings if present\n const enabledPluginNames = extractEnabledPlugins(userSettings);\n\n // Run all discovery functions in parallel\n const [claudeVersion, plugins, skills, rules, hooks, claudeMds, ecosystems] =\n await Promise.all([\n Promise.resolve(detectClaudeCodeVersion()),\n discoverPlugins(homeDir, enabledPluginNames),\n discoverSkills(homeDir, cwd),\n discoverRules(cwd),\n Promise.resolve(\n discoverHooks(userSettings, projectSettings, localSettings),\n ),\n discoverClaudeMd(homeDir, cwd),\n detectEcosystems(cwd, homeDir),\n ]);\n\n const snapshot: EnvironmentSnapshot = {\n generated_at: new Date().toISOString(),\n claude_code: claudeVersion,\n settings: {\n user: userSettings,\n project: projectSettings,\n local: localSettings,\n },\n installed_tools: {\n plugins,\n skills,\n rules,\n hooks,\n claude_md: claudeMds,\n },\n detected_ecosystems: ecosystems,\n };\n\n // Validate against schema before writing\n const validated = environmentSnapshotSchema.parse(snapshot);\n\n // Write atomically to analysis directory\n await ensureInit();\n await writeFileAtomic(\n paths.environmentSnapshot,\n JSON.stringify(validated),\n );\n\n return validated;\n}\n\n// --- Internal helpers ---\n\n/**\n * Detect Claude Code version by running `claude --version`.\n * Returns { version, version_known, compatible }.\n */\nfunction detectClaudeCodeVersion(): EnvironmentSnapshot['claude_code'] {\n try {\n const output = execFileSync('claude', ['--version'], {\n timeout: 3000,\n encoding: 'utf-8',\n stdio: ['pipe', 'pipe', 'pipe'],\n }).trim();\n\n const match = output.match(/^(\\d+\\.\\d+\\.\\d+)/);\n if (!match) {\n return { version: 'unknown', version_known: false, compatible: false };\n }\n\n const version = match[1];\n const compatible =\n compareSemver(version, KNOWN_COMPATIBLE_MIN) >= 0 &&\n compareSemver(version, KNOWN_COMPATIBLE_MAX) <= 0;\n\n return { version, version_known: true, compatible };\n } catch {\n return { version: 'unknown', version_known: false, compatible: false };\n }\n}\n\n/**\n * Safely read and parse a JSON settings file.\n * Returns parsed object or null if file is missing or invalid.\n */\nasync function readSettingsSafe(\n filePath: string,\n): Promise<unknown | null> {\n try {\n const raw = await readFile(filePath, 'utf-8');\n return JSON.parse(raw) as unknown;\n } catch {\n return null;\n }\n}\n\n/**\n * Extract enabled plugin names from user settings.\n */\nfunction extractEnabledPlugins(settings: unknown): string[] {\n if (!settings || typeof settings !== 'object') return [];\n const obj = settings as Record<string, unknown>;\n if (!Array.isArray(obj.enabledPlugins)) return [];\n\n return obj.enabledPlugins\n .map((p: unknown) => {\n if (typeof p === 'string') return p;\n if (p && typeof p === 'object' && 'name' in p) {\n return String((p as { name: unknown }).name);\n }\n return null;\n })\n .filter((n): n is string => n !== null);\n}\n\n/**\n * Discover installed plugins from ~/.claude/plugins/installed_plugins.json.\n * Cross-references with enabledPlugins from settings for accuracy.\n */\nasync function discoverPlugins(\n home: string,\n enabledPluginNames: string[],\n): Promise<EnvironmentSnapshot['installed_tools']['plugins']> {\n try {\n const pluginsFile = join(home, '.claude', 'plugins', 'installed_plugins.json');\n const raw = await readFile(pluginsFile, 'utf-8');\n const installed = JSON.parse(raw) as unknown[];\n\n if (!Array.isArray(installed)) return [];\n\n const plugins: EnvironmentSnapshot['installed_tools']['plugins'] = [];\n\n for (const entry of installed) {\n if (!entry || typeof entry !== 'object') continue;\n const plugin = entry as Record<string, unknown>;\n const name = String(plugin.name ?? '');\n const marketplace = String(plugin.marketplace ?? 'unknown');\n const scope = String(plugin.scope ?? 'user');\n const version = String(plugin.version ?? 'latest');\n\n const enabled = enabledPluginNames.includes(name);\n\n // Scan plugin cache for capabilities\n const capabilities = await scanPluginCapabilities(\n home,\n marketplace,\n name,\n version,\n );\n\n plugins.push({ name, marketplace, enabled, scope, capabilities });\n }\n\n return plugins;\n } catch {\n return [];\n }\n}\n\n/**\n * Scan plugin cache directory for capability subdirectories.\n */\nasync function scanPluginCapabilities(\n home: string,\n marketplace: string,\n pluginName: string,\n version: string,\n): Promise<string[]> {\n const knownCapabilities = ['commands', 'skills', 'hooks', 'agents'];\n const capabilities: string[] = [];\n\n try {\n const cacheDir = join(\n home, '.claude', 'plugins', 'cache',\n marketplace, pluginName, version,\n );\n const entries = await readdir(cacheDir, { withFileTypes: true });\n for (const entry of entries) {\n if (entry.isDirectory() && knownCapabilities.includes(entry.name)) {\n capabilities.push(entry.name);\n }\n }\n } catch {\n // Cache directory does not exist or is unreadable\n }\n\n return capabilities;\n}\n\n/**\n * Discover skill directories at user and project scopes.\n */\nasync function discoverSkills(\n home: string,\n cwd: string,\n): Promise<EnvironmentSnapshot['installed_tools']['skills']> {\n const skills: EnvironmentSnapshot['installed_tools']['skills'] = [];\n\n // User-scope skills: ~/.claude/skills/\n try {\n const userSkillsDir = join(home, '.claude', 'skills');\n const entries = await readdir(userSkillsDir, { withFileTypes: true });\n for (const entry of entries) {\n if (entry.isDirectory()) {\n skills.push({ name: entry.name, scope: 'user' });\n }\n }\n } catch {\n // Directory does not exist\n }\n\n // Project-scope skills: {cwd}/.claude/skills/\n try {\n const projectSkillsDir = join(cwd, '.claude', 'skills');\n const entries = await readdir(projectSkillsDir, { withFileTypes: true });\n for (const entry of entries) {\n if (entry.isDirectory()) {\n skills.push({ name: entry.name, scope: 'project' });\n }\n }\n } catch {\n // Directory does not exist\n }\n\n return skills;\n}\n\n/**\n * Discover rule directories at project scope.\n */\nasync function discoverRules(\n cwd: string,\n): Promise<EnvironmentSnapshot['installed_tools']['rules']> {\n const rules: EnvironmentSnapshot['installed_tools']['rules'] = [];\n\n try {\n const rulesDir = join(cwd, '.claude', 'rules');\n const entries = await readdir(rulesDir, { withFileTypes: true });\n for (const entry of entries) {\n if (entry.isDirectory()) {\n rules.push({ name: entry.name, scope: 'project' });\n }\n }\n } catch {\n // Directory does not exist\n }\n\n return rules;\n}\n\n/**\n * Extract hook definitions from settings objects at all 3 scopes.\n */\nfunction discoverHooks(\n userSettings: unknown,\n projectSettings: unknown,\n localSettings: unknown,\n): EnvironmentSnapshot['installed_tools']['hooks'] {\n const hooks: EnvironmentSnapshot['installed_tools']['hooks'] = [];\n\n extractHooksFromSettings(userSettings, 'user', hooks);\n extractHooksFromSettings(projectSettings, 'project', hooks);\n extractHooksFromSettings(localSettings, 'local', hooks);\n\n return hooks;\n}\n\n/**\n * Extract hooks from a single settings object and append to the hooks array.\n */\nfunction extractHooksFromSettings(\n settings: unknown,\n scope: 'user' | 'project' | 'local',\n hooks: EnvironmentSnapshot['installed_tools']['hooks'],\n): void {\n if (!settings || typeof settings !== 'object') return;\n const obj = settings as Record<string, unknown>;\n if (!obj.hooks || typeof obj.hooks !== 'object') return;\n\n const hooksConfig = obj.hooks as Record<string, unknown>;\n for (const [event, defs] of Object.entries(hooksConfig)) {\n if (!Array.isArray(defs)) continue;\n for (const def of defs) {\n if (!def || typeof def !== 'object') continue;\n const hookDef = def as Record<string, unknown>;\n const type = String(hookDef.type ?? 'command');\n hooks.push({ event, scope, type });\n }\n }\n}\n\n/**\n * Discover CLAUDE.md files at common locations.\n */\nasync function discoverClaudeMd(\n home: string,\n cwd: string,\n): Promise<EnvironmentSnapshot['installed_tools']['claude_md']> {\n const locations = [\n join(cwd, 'CLAUDE.md'),\n join(cwd, '.claude', 'CLAUDE.md'),\n join(home, '.claude', 'CLAUDE.md'),\n ];\n\n const results: EnvironmentSnapshot['installed_tools']['claude_md'] = [];\n\n for (const path of locations) {\n let exists = false;\n try {\n await access(path, constants.F_OK);\n exists = true;\n } catch {\n // File does not exist\n }\n results.push({ path, exists });\n }\n\n return results;\n}\n\n/**\n * Detect known ecosystems by checking for characteristic directories.\n */\nasync function detectEcosystems(\n cwd: string,\n home: string,\n): Promise<string[]> {\n const ecosystems: string[] = [];\n\n // GSD: check for .planning/ directory\n try {\n await access(join(cwd, '.planning'), constants.F_OK);\n ecosystems.push('gsd');\n } catch {\n // No GSD detected\n }\n\n // Cog: check for 'cog' in ~/.claude/skills/\n try {\n const skillsDir = join(home, '.claude', 'skills');\n const entries = await readdir(skillsDir);\n if (entries.some((e) => e.toLowerCase().includes('cog'))) {\n ecosystems.push('cog');\n }\n } catch {\n // Skills directory does not exist\n }\n\n return ecosystems;\n}\n\n/**\n * Compare two semver strings (X.Y.Z format).\n * Returns -1, 0, or 1.\n */\nfunction compareSemver(a: string, b: string): number {\n const partsA = a.split('.').map(Number);\n const partsB = b.split('.').map(Number);\n\n for (let i = 0; i < 3; i++) {\n const numA = partsA[i] ?? 0;\n const numB = partsB[i] ?? 0;\n if (numA < numB) return -1;\n if (numA > numB) return 1;\n }\n\n return 0;\n}\n","// Classifier for repeated short prompts.\n// Detects prompts used multiple times across sessions and recommends\n// creating a hook for automation. Short = under 50 words.\n\nimport type { Summary, EnvironmentSnapshot } from '../schemas.js';\nimport type { Recommendation, AnalysisConfig } from '../../schemas/recommendation.js';\n\n/**\n * Truncate a string to maxLen characters, adding ellipsis if truncated.\n */\nfunction truncate(str: string, maxLen: number): string {\n if (str.length <= maxLen) return str;\n return str.slice(0, maxLen - 3) + '...';\n}\n\n/**\n * Classify repeated short prompts (< 50 words) as HOOK recommendations.\n *\n * HIGH confidence: count >= 10 AND sessions >= 3\n * MEDIUM confidence: count >= 5 (already past min threshold)\n *\n * Skips prompts with word count > 50 (handled by long-prompts classifier).\n */\nexport function classifyRepeatedPrompts(\n summary: Summary,\n _snapshot: EnvironmentSnapshot,\n config: AnalysisConfig,\n): Recommendation[] {\n const recommendations: Recommendation[] = [];\n const threshold = config.thresholds.repeated_prompt_min_count;\n\n for (let i = 0; i < summary.top_repeated_prompts.length; i++) {\n const entry = summary.top_repeated_prompts[i];\n\n if (entry.count < threshold) continue;\n\n // Skip long prompts -- handled by long-prompts classifier\n const wordCount = entry.prompt.split(/\\s+/).length;\n if (wordCount > 50) continue;\n\n const confidence: 'HIGH' | 'MEDIUM' =\n entry.count >= config.thresholds.repeated_prompt_high_count &&\n entry.sessions >= config.thresholds.repeated_prompt_high_sessions\n ? 'HIGH'\n : 'MEDIUM';\n\n const truncatedPrompt = truncate(entry.prompt, 60);\n\n recommendations.push({\n id: `rec-repeated-${i}`,\n target: 'HOOK',\n confidence,\n pattern_type: 'repeated_prompt',\n title: `Repeated prompt: \"${truncatedPrompt}\"`,\n description: `This prompt has been used ${entry.count} times across ${entry.sessions} sessions. Consider creating a hook or alias to automate this.`,\n evidence: {\n count: entry.count,\n sessions: entry.sessions,\n examples: [entry.prompt],\n },\n suggested_action: `Create a UserPromptSubmit hook that detects \"${truncatedPrompt}\" and auto-executes the intended action.`,\n });\n }\n\n return recommendations;\n}\n","// Classifier for long repeated prompts.\n// Detects prompts with high word count that are repeated, and recommends\n// converting them into a reusable skill.\n\nimport type { Summary, EnvironmentSnapshot } from '../schemas.js';\nimport type { Recommendation, AnalysisConfig } from '../../schemas/recommendation.js';\n\n/**\n * Classify long repeated prompts as SKILL recommendations.\n *\n * HIGH confidence: length >= 300 words AND count >= 3\n * MEDIUM confidence: length >= 200 words AND count >= 2 (past min thresholds)\n *\n * Skips entries below long_prompt_min_words or long_prompt_min_count.\n */\nexport function classifyLongPrompts(\n summary: Summary,\n _snapshot: EnvironmentSnapshot,\n config: AnalysisConfig,\n): Recommendation[] {\n const recommendations: Recommendation[] = [];\n\n for (let i = 0; i < summary.long_prompts.length; i++) {\n const entry = summary.long_prompts[i];\n\n if (entry.length < config.thresholds.long_prompt_min_words) continue;\n if (entry.count < config.thresholds.long_prompt_min_count) continue;\n\n const confidence: 'HIGH' | 'MEDIUM' =\n entry.count >= config.thresholds.long_prompt_high_count &&\n entry.length >= config.thresholds.long_prompt_high_words\n ? 'HIGH'\n : 'MEDIUM';\n\n recommendations.push({\n id: `rec-long-${i}`,\n target: 'SKILL',\n confidence,\n pattern_type: 'long_prompt',\n title: `Long repeated prompt (${entry.length} words, ${entry.count}x)`,\n description: `A ${entry.length}-word prompt has been used ${entry.count} times. Consider converting it to a reusable skill.`,\n evidence: {\n count: entry.count,\n examples: [entry.prompt_preview],\n },\n suggested_action: 'Create a skill in .claude/skills/ that encapsulates this prompt as a reusable workflow.',\n });\n }\n\n return recommendations;\n}\n","// Classifier for permission approval patterns.\n// Detects tools that are frequently approved across multiple sessions\n// and recommends adding them to allowedTools in settings.json.\n\nimport type { Summary, EnvironmentSnapshot } from '../schemas.js';\nimport type { Recommendation, AnalysisConfig } from '../../schemas/recommendation.js';\n\n/**\n * Classify permission approval patterns as SETTINGS recommendations.\n *\n * HIGH confidence: count >= 15 AND sessions >= 4\n * MEDIUM confidence: count >= 10 AND sessions >= 3 (past min thresholds)\n *\n * Skips entries below permission_approval_min_count or permission_approval_min_sessions.\n */\nexport function classifyPermissionPatterns(\n summary: Summary,\n _snapshot: EnvironmentSnapshot,\n config: AnalysisConfig,\n): Recommendation[] {\n const recommendations: Recommendation[] = [];\n\n for (let i = 0; i < summary.permission_patterns.length; i++) {\n const entry = summary.permission_patterns[i];\n\n if (entry.count < config.thresholds.permission_approval_min_count) continue;\n if (entry.sessions < config.thresholds.permission_approval_min_sessions) continue;\n\n const confidence: 'HIGH' | 'MEDIUM' =\n entry.count >= config.thresholds.permission_approval_high_count &&\n entry.sessions >= config.thresholds.permission_approval_high_sessions\n ? 'HIGH'\n : 'MEDIUM';\n\n recommendations.push({\n id: `rec-permission-always-approved-${i}`,\n target: 'SETTINGS',\n confidence,\n pattern_type: 'permission-always-approved',\n title: `Frequently approved tool: ${entry.tool_name}`,\n description: `You have approved \"${entry.tool_name}\" ${entry.count} times across ${entry.sessions} sessions. Consider adding it to allowedTools in settings.json.`,\n evidence: {\n count: entry.count,\n sessions: entry.sessions,\n examples: [`${entry.tool_name} approved ${entry.count} times`],\n },\n suggested_action: `Add \"${entry.tool_name}\" to the \"allow\" array in ~/.claude/settings.json permissions.`,\n });\n }\n\n return recommendations;\n}\n","// Classifier for code correction patterns.\n// Detects high-usage code-modification tools (Write, Edit, MultiEdit) and\n// recommends creating rules to standardize recurring modification patterns.\n// This is a LOW-confidence heuristic: the summary pre-aggregates tool usage\n// without per-tool failure rates, so we use a simplified approach.\n\nimport type { Summary, EnvironmentSnapshot } from '../schemas.js';\nimport type { Recommendation, AnalysisConfig } from '../../schemas/recommendation.js';\n\n// Tools that modify code -- high usage suggests recurring patterns\nconst CODE_MODIFICATION_TOOLS = new Set(['Write', 'Edit', 'MultiEdit']);\n\n// Minimum usage count to suggest rule creation (heuristic threshold)\nconst HIGH_USAGE_THRESHOLD = 20;\n\n/**\n * Classify code correction patterns as RULE recommendations.\n *\n * LOW confidence: code-modification tool count >= 20 uses.\n *\n * Since summary.tool_frequency does not track per-tool failure rates,\n * this classifier uses a simplified heuristic: tools that modify files\n * (Write, Edit, MultiEdit) with high usage counts are candidates for\n * coding rules or conventions.\n */\nexport function classifyCodeCorrections(\n summary: Summary,\n _snapshot: EnvironmentSnapshot,\n _config: AnalysisConfig,\n): Recommendation[] {\n const recommendations: Recommendation[] = [];\n let index = 0;\n\n for (const entry of summary.tool_frequency) {\n // Only consider code-modification tools\n if (!CODE_MODIFICATION_TOOLS.has(entry.tool_name)) continue;\n\n // Require high usage count as a proxy for recurring patterns\n if (entry.count < HIGH_USAGE_THRESHOLD) continue;\n\n recommendations.push({\n id: `rec-correction-${index}`,\n target: 'RULE',\n confidence: 'LOW',\n pattern_type: 'code_correction',\n title: `Frequent code modifications with ${entry.tool_name} (${entry.count} uses)`,\n description: `The ${entry.tool_name} tool has been used ${entry.count} times. Review for recurring patterns that could become a coding rule or convention.`,\n evidence: {\n count: entry.count,\n examples: [entry.tool_name],\n },\n suggested_action: `Review recent ${entry.tool_name} usage for recurring patterns. If a consistent code style or approach emerges, create a rule in .claude/rules/.`,\n });\n\n index++;\n }\n\n return recommendations;\n}\n","// Classifier for personal information mentions.\n// Detects prompts containing personal keywords (name, location, preferences)\n// and recommends storing them in memory for automatic context.\n\nimport type { Summary, EnvironmentSnapshot } from '../schemas.js';\nimport type { Recommendation, AnalysisConfig } from '../../schemas/recommendation.js';\n\n// Keywords that indicate personal information or preferences\nconst PERSONAL_KEYWORDS = [\n 'my name is',\n 'i live in',\n 'i work at',\n 'i prefer',\n 'my email',\n 'my project',\n 'always use',\n 'never use',\n];\n\n// Minimum repeat count to avoid flagging one-off mentions\nconst MIN_COUNT = 2;\n\n/**\n * Classify personal info mentions as MEMORY recommendations.\n *\n * LOW confidence for all matches -- keyword matching is inherently heuristic.\n *\n * Deduplicates by keyword: each keyword produces at most one recommendation,\n * using the first matching prompt as the example.\n */\nexport function classifyPersonalInfo(\n summary: Summary,\n _snapshot: EnvironmentSnapshot,\n _config: AnalysisConfig,\n): Recommendation[] {\n const recommendations: Recommendation[] = [];\n const matchedKeywords = new Set<string>();\n let index = 0;\n\n for (const entry of summary.top_repeated_prompts) {\n if (entry.count < MIN_COUNT) continue;\n\n const lowerPrompt = entry.prompt.toLowerCase();\n\n for (const keyword of PERSONAL_KEYWORDS) {\n if (matchedKeywords.has(keyword)) continue;\n if (!lowerPrompt.includes(keyword)) continue;\n\n matchedKeywords.add(keyword);\n\n recommendations.push({\n id: `rec-personal-${index}`,\n target: 'MEMORY',\n confidence: 'LOW',\n pattern_type: 'personal_info',\n title: `Personal preference detected: \"${keyword}...\"`,\n description: `A prompt mentioning personal information (\"${keyword}\") has appeared ${entry.count} times. Consider storing this in memory for automatic context.`,\n evidence: {\n count: entry.count,\n sessions: entry.sessions,\n examples: [entry.prompt],\n },\n suggested_action: 'Add this information to memory (e.g., CLAUDE.md or a memory file) so Claude Code can use it without being reminded.',\n });\n\n index++;\n }\n }\n\n return recommendations;\n}\n","// Classifier for configuration drift detection.\n// Detects potential conflicts and redundancies in the user's Claude Code\n// configuration: hook-rule overlaps, multiple CLAUDE.md files, and\n// excessive hook counts.\n\nimport type { Summary, EnvironmentSnapshot } from '../schemas.js';\nimport type { Recommendation, AnalysisConfig } from '../../schemas/recommendation.js';\n\n// Threshold for excessive hooks across all scopes\nconst MAX_HOOKS_BEFORE_REVIEW = 10;\n\n/**\n * Classify configuration drift patterns.\n *\n * All config drift recommendations are LOW confidence.\n *\n * Check 1: Hook-Rule overlap -- hooks and rules with matching names/events\n * suggest duplicated behavior that should be consolidated.\n * Check 2: Multiple CLAUDE.md -- multiple existing CLAUDE.md files may\n * contain contradictory instructions.\n * Check 3: Hook count heuristic -- more than 10 hooks suggests potential\n * redundancy that warrants review.\n */\nexport function classifyConfigDrift(\n _summary: Summary,\n snapshot: EnvironmentSnapshot,\n _config: AnalysisConfig,\n): Recommendation[] {\n const recommendations: Recommendation[] = [];\n let index = 0;\n\n // Check 1: Hook-Rule overlap\n const hookEvents = new Set(snapshot.installed_tools.hooks.map(h => h.event));\n const ruleNames = new Set(snapshot.installed_tools.rules.map(r => r.name));\n\n for (const overlap of hookEvents) {\n if (!ruleNames.has(overlap)) continue;\n\n recommendations.push({\n id: `rec-drift-${index}`,\n target: 'RULE',\n confidence: 'LOW',\n pattern_type: 'config_drift',\n title: `Hook-rule overlap detected: \"${overlap}\"`,\n description: `Both a hook (event: \"${overlap}\") and a rule (name: \"${overlap}\") exist. This may indicate duplicated behavior that should be consolidated into one mechanism.`,\n evidence: {\n count: 2,\n examples: [`Hook event: ${overlap}`, `Rule name: ${overlap}`],\n },\n suggested_action: `Review the hook and rule for \"${overlap}\". If they serve the same purpose, consolidate into the more appropriate mechanism (hooks for 100% reliability, rules for guidance).`,\n });\n\n index++;\n }\n\n // Check 2: Multiple CLAUDE.md files\n const existingClaudeMd = snapshot.installed_tools.claude_md.filter(c => c.exists);\n if (existingClaudeMd.length > 1) {\n recommendations.push({\n id: `rec-drift-${index}`,\n target: 'CLAUDE_MD',\n confidence: 'LOW',\n pattern_type: 'config_drift',\n title: `Multiple CLAUDE.md files detected (${existingClaudeMd.length})`,\n description: `Found ${existingClaudeMd.length} existing CLAUDE.md files. Multiple CLAUDE.md files may contain contradictory instructions. Review for consistency.`,\n evidence: {\n count: existingClaudeMd.length,\n examples: existingClaudeMd.slice(0, 3).map(c => c.path),\n },\n suggested_action: 'Review all CLAUDE.md files for contradictions or redundancies. Consider consolidating shared instructions into the most appropriate scope.',\n });\n\n index++;\n }\n\n // Check 3: Hook count heuristic\n if (snapshot.installed_tools.hooks.length > MAX_HOOKS_BEFORE_REVIEW) {\n recommendations.push({\n id: `rec-drift-${index}`,\n target: 'HOOK',\n confidence: 'LOW',\n pattern_type: 'config_drift',\n title: `Excessive hook count (${snapshot.installed_tools.hooks.length} hooks)`,\n description: `Found ${snapshot.installed_tools.hooks.length} hooks across all scopes. This many hooks may indicate redundancy or performance concerns. Review for consolidation.`,\n evidence: {\n count: snapshot.installed_tools.hooks.length,\n examples: snapshot.installed_tools.hooks.slice(0, 3).map(h => `${h.event} (${h.scope})`),\n },\n suggested_action: 'Review all hooks for overlapping functionality. Consider combining hooks that trigger on the same event or serve similar purposes.',\n });\n }\n\n return recommendations;\n}\n","// Classifier for ecosystem-aware routing adaptations.\n// Produces recommendations based on detected ecosystems (GSD, Cog) and\n// Claude Code version compatibility. Enhances routing suggestions with\n// ecosystem-specific context.\n\nimport type { Summary, EnvironmentSnapshot } from '../schemas.js';\nimport type { Recommendation, AnalysisConfig } from '../../schemas/recommendation.js';\n\n// Minimum prompt repeat count to consider it a multi-step workflow candidate\nconst MULTI_STEP_MIN_COUNT = 3;\n\n/**\n * Classify ecosystem-specific adaptations and version recommendations.\n *\n * Version check (RTG-10): MEDIUM confidence when Claude Code version is\n * outside the tested compatible range.\n *\n * GSD ecosystem (RTG-09): LOW confidence SKILL recommendation when GSD\n * is detected and repeated multi-step prompts exist.\n *\n * Cog ecosystem (RTG-09): LOW confidence MEMORY recommendation when Cog\n * is detected, routing memory management to Cog tiers.\n */\nexport function classifyEcosystemAdaptations(\n summary: Summary,\n snapshot: EnvironmentSnapshot,\n _config: AnalysisConfig,\n): Recommendation[] {\n const recommendations: Recommendation[] = [];\n let index = 0;\n\n // Version check (RTG-10)\n if (\n snapshot.claude_code.version_known &&\n !snapshot.claude_code.compatible &&\n snapshot.claude_code.version !== 'unknown'\n ) {\n recommendations.push({\n id: `rec-ecosystem-${index}`,\n target: 'CLAUDE_MD',\n confidence: 'MEDIUM',\n pattern_type: 'version_update',\n title: `Claude Code version ${snapshot.claude_code.version} detected (outside tested range)`,\n description: `Your Claude Code version (${snapshot.claude_code.version}) is outside the tested compatible range. New features may be available that change optimal configuration strategies.`,\n evidence: {\n count: 1,\n examples: [`Version: ${snapshot.claude_code.version}`],\n },\n suggested_action: `Review Claude Code changelog for version ${snapshot.claude_code.version}. New hook events, permission models, or settings may require harness-evolve configuration updates.`,\n });\n index++;\n }\n\n // GSD ecosystem (RTG-09)\n if (snapshot.detected_ecosystems.includes('gsd')) {\n // Look for repeated multi-step prompts that could be GSD workflows\n const multiStepPrompts = summary.top_repeated_prompts.filter(\n p => p.count >= MULTI_STEP_MIN_COUNT,\n );\n\n if (multiStepPrompts.length > 0) {\n const topPrompt = multiStepPrompts[0];\n recommendations.push({\n id: `rec-ecosystem-${index}`,\n target: 'SKILL',\n confidence: 'LOW',\n pattern_type: 'ecosystem_gsd',\n title: 'GSD workflow detected -- consider /gsd slash commands',\n description: 'GSD is installed in this project. Repeated multi-step prompts may be better served by GSD planning phases or slash commands rather than standalone skills.',\n evidence: {\n count: multiStepPrompts.length,\n examples: [topPrompt.prompt],\n },\n suggested_action: 'Review repeated prompts and consider if they map to GSD phases (/gsd:plan-phase, /gsd:execute-phase) or custom slash commands.',\n ecosystem_context: 'GSD detected: Use /gsd slash commands and .planning patterns for multi-step workflows instead of standalone skills',\n });\n index++;\n }\n }\n\n // Cog ecosystem (RTG-09)\n if (snapshot.detected_ecosystems.includes('cog')) {\n recommendations.push({\n id: `rec-ecosystem-${index}`,\n target: 'MEMORY',\n confidence: 'LOW',\n pattern_type: 'ecosystem_cog',\n title: 'Cog memory system detected -- route memory to Cog tiers',\n description: \"Cog is installed. Personal information and contextual preferences should be routed to Cog's tiered memory system rather than raw CLAUDE.md entries.\",\n evidence: {\n count: 1,\n examples: ['Cog detected in ~/.claude/skills/'],\n },\n suggested_action: 'Use /reflect and /evolve Cog commands for memory management instead of manually editing CLAUDE.md.',\n ecosystem_context: 'Cog detected: Route memory entries to Cog tiers (/reflect, /evolve) instead of raw CLAUDE.md',\n });\n }\n\n return recommendations;\n}\n","// Pure function to compute user experience level from environment snapshot.\n// Scores each tool category by weight and maps total score to a tier:\n// 0 -> newcomer, 1-29 -> intermediate, 30+ -> power_user.\n// Weights reflect automation investment: plugins (10), hooks (8), ecosystems (7),\n// rules (6), skills (5), claude_md (3).\n\nimport type { EnvironmentSnapshot } from './schemas.js';\nimport type { ExperienceLevel, ExperienceTier } from '../schemas/onboarding.js';\n\nexport function computeExperienceLevel(snapshot: EnvironmentSnapshot): ExperienceLevel {\n const hooks = snapshot.installed_tools.hooks.length;\n const rules = snapshot.installed_tools.rules.length;\n const skills = snapshot.installed_tools.skills.length;\n const plugins = snapshot.installed_tools.plugins.length;\n const claudeMd = snapshot.installed_tools.claude_md.filter(c => c.exists).length;\n const ecosystems = snapshot.detected_ecosystems.length;\n\n const score = Math.min(100,\n hooks * 8 + rules * 6 + skills * 5 +\n plugins * 10 + claudeMd * 3 + ecosystems * 7,\n );\n\n const tier: ExperienceTier =\n score === 0 ? 'newcomer' :\n score < 30 ? 'intermediate' :\n 'power_user';\n\n return {\n tier,\n score,\n breakdown: { hooks, rules, skills, plugins, claude_md: claudeMd, ecosystems },\n };\n}\n","// Classifier for tiered onboarding detection.\n// Produces tier-appropriate recommendations based on user experience level:\n// newcomer (score=0) gets \"start here\" guidance for missing config,\n// power_user (score>=30) gets \"optimize\" suggestions,\n// intermediate (1-29) gets no onboarding-specific recs (handled by other classifiers).\n\nimport type { Summary, EnvironmentSnapshot } from '../schemas.js';\nimport type { Recommendation, AnalysisConfig } from '../../schemas/recommendation.js';\nimport { computeExperienceLevel } from '../experience-level.js';\n\n/**\n * Classify onboarding needs based on user experience tier.\n *\n * Newcomer (score=0): Up to 3 MEDIUM-confidence \"start here\" recommendations\n * for missing hooks, rules, and CLAUDE.md.\n *\n * Power user (score>=30): 1 LOW-confidence \"optimize\" recommendation\n * suggesting consolidation review.\n *\n * Intermediate (1-29): No recommendations (existing classifiers handle\n * pattern-specific suggestions).\n */\nexport function classifyOnboarding(\n _summary: Summary,\n snapshot: EnvironmentSnapshot,\n _config: AnalysisConfig,\n): Recommendation[] {\n const level = computeExperienceLevel(snapshot);\n const recommendations: Recommendation[] = [];\n let index = 0;\n\n if (level.tier === 'newcomer') {\n // Suggest missing hooks\n if (level.breakdown.hooks === 0) {\n recommendations.push({\n id: `rec-onboarding-${index}`,\n target: 'HOOK',\n confidence: 'MEDIUM',\n pattern_type: 'onboarding_start_hooks',\n title: 'Start automating: create your first hook',\n description:\n 'Hooks run automatically on Claude Code lifecycle events (pre-commit, tool use, session start). ' +\n 'Start with a formatting or test-on-save hook to experience automation benefits.',\n evidence: {\n count: 0,\n examples: ['No hooks detected in your environment'],\n },\n suggested_action:\n 'Add a hook in .claude/settings.json hooks section for automation.',\n });\n index++;\n }\n\n // Suggest missing rules\n if (level.breakdown.rules === 0) {\n recommendations.push({\n id: `rec-onboarding-${index}`,\n target: 'RULE',\n confidence: 'MEDIUM',\n pattern_type: 'onboarding_start_rules',\n title: 'Define coding preferences: add your first rule',\n description:\n 'Rules (.claude/rules/) codify conventions that Claude follows automatically. ' +\n 'They persist across sessions and ensure consistent behavior.',\n evidence: {\n count: 0,\n examples: ['No rules detected in your environment'],\n },\n suggested_action:\n 'Create .claude/rules/ directory with a rule for your preferred coding style.',\n });\n index++;\n }\n\n // Suggest missing CLAUDE.md\n if (level.breakdown.claude_md === 0) {\n recommendations.push({\n id: `rec-onboarding-${index}`,\n target: 'CLAUDE_MD',\n confidence: 'MEDIUM',\n pattern_type: 'onboarding_start_claudemd',\n title: 'Set project context: create CLAUDE.md',\n description:\n 'CLAUDE.md gives Claude project-specific context — tech stack, conventions, and constraints. ' +\n 'It is loaded automatically at the start of every conversation.',\n evidence: {\n count: 0,\n examples: ['No CLAUDE.md files detected in your environment'],\n },\n suggested_action:\n 'Create CLAUDE.md in your project root with project description and conventions.',\n });\n }\n } else if (level.tier === 'power_user') {\n recommendations.push({\n id: 'rec-onboarding-3',\n target: 'SETTINGS',\n confidence: 'LOW',\n pattern_type: 'onboarding_optimize',\n title: 'Consider mechanizing recurring patterns',\n description:\n 'Your extensive configuration suggests active automation investment. ' +\n 'Review for redundancy or upgrade opportunities — hooks and rules with overlapping concerns can be consolidated.',\n evidence: {\n count: level.score,\n examples: [\n `${level.breakdown.hooks} hooks, ${level.breakdown.rules} rules, ${level.breakdown.plugins} plugins installed`,\n ],\n },\n suggested_action:\n 'Review your hooks and rules for overlapping concerns that could be consolidated.',\n });\n }\n // Intermediate: return empty array\n\n return recommendations;\n}\n","// Classifier registry: defines the Classifier type and holds all registered\n// classifier functions. New classifiers are added by importing and pushing\n// to the classifiers array.\n\nimport type { Summary, EnvironmentSnapshot } from '../schemas.js';\nimport type { Recommendation, AnalysisConfig } from '../../schemas/recommendation.js';\nimport { classifyRepeatedPrompts } from './repeated-prompts.js';\nimport { classifyLongPrompts } from './long-prompts.js';\nimport { classifyPermissionPatterns } from './permission-patterns.js';\nimport { classifyCodeCorrections } from './code-corrections.js';\nimport { classifyPersonalInfo } from './personal-info.js';\nimport { classifyConfigDrift } from './config-drift.js';\nimport { classifyEcosystemAdaptations } from './ecosystem-adapter.js';\nimport { classifyOnboarding } from './onboarding.js';\n\nexport type Classifier = (\n summary: Summary,\n snapshot: EnvironmentSnapshot,\n config: AnalysisConfig,\n) => Recommendation[];\n\n// Registered classifiers, evaluated in order by the analyzer\nexport const classifiers: Classifier[] = [\n classifyRepeatedPrompts,\n classifyLongPrompts,\n classifyPermissionPatterns,\n classifyCodeCorrections,\n classifyPersonalInfo,\n classifyConfigDrift,\n classifyEcosystemAdaptations,\n classifyOnboarding,\n];\n","// Recommendation and analysis result schemas.\n// Defines the output contracts for the analysis engine: routing targets,\n// confidence tiers, recommendation structure, and analysis configuration.\n\nimport { z } from 'zod/v4';\n\nexport const routingTargetSchema = z.enum([\n 'HOOK',\n 'SKILL',\n 'RULE',\n 'CLAUDE_MD',\n 'MEMORY',\n 'SETTINGS',\n]);\nexport type RoutingTarget = z.infer<typeof routingTargetSchema>;\n\nexport const confidenceSchema = z.enum(['HIGH', 'MEDIUM', 'LOW']);\nexport type Confidence = z.infer<typeof confidenceSchema>;\n\nexport const patternTypeSchema = z.enum([\n 'repeated_prompt',\n 'long_prompt',\n 'permission-always-approved',\n 'code_correction',\n 'personal_info',\n 'config_drift',\n 'version_update',\n 'ecosystem_gsd',\n 'ecosystem_cog',\n 'onboarding_start_hooks',\n 'onboarding_start_rules',\n 'onboarding_start_claudemd',\n 'onboarding_optimize',\n 'scan_redundancy',\n 'scan_missing_mechanization',\n 'scan_stale_reference',\n]);\nexport type PatternType = z.infer<typeof patternTypeSchema>;\n\nexport const recommendationSchema = z.object({\n id: z.string(),\n target: routingTargetSchema,\n confidence: confidenceSchema,\n pattern_type: patternTypeSchema,\n title: z.string(),\n description: z.string(),\n evidence: z.object({\n count: z.number(),\n sessions: z.number().optional(),\n examples: z.array(z.string()).max(3),\n }),\n suggested_action: z.string(),\n ecosystem_context: z.string().optional(),\n});\nexport type Recommendation = z.infer<typeof recommendationSchema>;\n\n// Default threshold values for classifiers\nconst DEFAULT_THRESHOLDS = {\n repeated_prompt_min_count: 5,\n repeated_prompt_high_count: 10,\n repeated_prompt_high_sessions: 3,\n repeated_prompt_medium_sessions: 2,\n long_prompt_min_words: 200,\n long_prompt_min_count: 2,\n long_prompt_high_words: 300,\n long_prompt_high_count: 3,\n permission_approval_min_count: 10,\n permission_approval_min_sessions: 3,\n permission_approval_high_count: 15,\n permission_approval_high_sessions: 4,\n code_correction_min_failure_rate: 0.3,\n code_correction_min_failures: 3,\n} as const;\n\nexport const analysisConfigSchema = z.object({\n thresholds: z.object({\n repeated_prompt_min_count: z.number().default(DEFAULT_THRESHOLDS.repeated_prompt_min_count),\n repeated_prompt_high_count: z.number().default(DEFAULT_THRESHOLDS.repeated_prompt_high_count),\n repeated_prompt_high_sessions: z.number().default(DEFAULT_THRESHOLDS.repeated_prompt_high_sessions),\n repeated_prompt_medium_sessions: z.number().default(DEFAULT_THRESHOLDS.repeated_prompt_medium_sessions),\n long_prompt_min_words: z.number().default(DEFAULT_THRESHOLDS.long_prompt_min_words),\n long_prompt_min_count: z.number().default(DEFAULT_THRESHOLDS.long_prompt_min_count),\n long_prompt_high_words: z.number().default(DEFAULT_THRESHOLDS.long_prompt_high_words),\n long_prompt_high_count: z.number().default(DEFAULT_THRESHOLDS.long_prompt_high_count),\n permission_approval_min_count: z.number().default(DEFAULT_THRESHOLDS.permission_approval_min_count),\n permission_approval_min_sessions: z.number().default(DEFAULT_THRESHOLDS.permission_approval_min_sessions),\n permission_approval_high_count: z.number().default(DEFAULT_THRESHOLDS.permission_approval_high_count),\n permission_approval_high_sessions: z.number().default(DEFAULT_THRESHOLDS.permission_approval_high_sessions),\n code_correction_min_failure_rate: z.number().default(DEFAULT_THRESHOLDS.code_correction_min_failure_rate),\n code_correction_min_failures: z.number().default(DEFAULT_THRESHOLDS.code_correction_min_failures),\n }).default(() => ({ ...DEFAULT_THRESHOLDS })),\n max_recommendations: z.number().default(20),\n}).default(() => ({\n thresholds: { ...DEFAULT_THRESHOLDS },\n max_recommendations: 20,\n}));\nexport type AnalysisConfig = z.infer<typeof analysisConfigSchema>;\n\nexport const analysisResultSchema = z.object({\n generated_at: z.iso.datetime(),\n summary_period: z.object({\n since: z.string(),\n until: z.string(),\n days: z.number(),\n }),\n recommendations: z.array(recommendationSchema),\n metadata: z.object({\n classifier_count: z.number(),\n patterns_evaluated: z.number(),\n environment_ecosystems: z.array(z.string()),\n claude_code_version: z.string(),\n }),\n});\nexport type AnalysisResult = z.infer<typeof analysisResultSchema>;\n","// Main analysis orchestrator: iterates all registered classifiers,\n// collects recommendations, sorts by confidence and evidence, caps\n// at max_recommendations, and returns a validated AnalysisResult.\n\nimport { classifiers } from './classifiers/index.js';\nimport type { Summary, EnvironmentSnapshot } from './schemas.js';\nimport {\n analysisConfigSchema,\n analysisResultSchema,\n type AnalysisConfig,\n type AnalysisResult,\n type Recommendation,\n} from '../schemas/recommendation.js';\nimport type { OutcomeSummary } from '../schemas/onboarding.js';\n\n// Confidence tier numeric ordering for sorting (ascending = higher priority)\nconst CONFIDENCE_ORDER: Record<string, number> = {\n HIGH: 0,\n MEDIUM: 1,\n LOW: 2,\n};\n\n/**\n * Sort recommendations by confidence (HIGH first), then by evidence.count\n * descending within the same tier.\n */\nfunction sortRecommendations(a: Recommendation, b: Recommendation): number {\n const confDiff =\n (CONFIDENCE_ORDER[a.confidence] ?? 3) -\n (CONFIDENCE_ORDER[b.confidence] ?? 3);\n if (confDiff !== 0) return confDiff;\n return b.evidence.count - a.evidence.count;\n}\n\n/**\n * Adjust recommendation confidence based on historical outcome data.\n * Pattern types with >30% revert rate (persistence_rate < 0.7) get\n * downgraded by one tier: HIGH->MEDIUM, MEDIUM->LOW, LOW stays LOW.\n */\nexport function adjustConfidence(\n recommendations: Recommendation[],\n summaries: OutcomeSummary[],\n): Recommendation[] {\n const rateByType = new Map(\n summaries.map((s) => [s.pattern_type, s.persistence_rate]),\n );\n\n return recommendations.map((rec) => {\n const rate = rateByType.get(rec.pattern_type);\n if (rate === undefined || rate >= 0.7) return rec;\n\n // Downgrade one tier\n const downgraded: Record<string, string> = {\n HIGH: 'MEDIUM',\n MEDIUM: 'LOW',\n LOW: 'LOW',\n };\n\n return {\n ...rec,\n confidence: (downgraded[rec.confidence] ??\n rec.confidence) as Recommendation['confidence'],\n };\n });\n}\n\n/**\n * Analyze a pre-processed summary and environment snapshot to produce\n * structured recommendations.\n *\n * @param summary - Pre-processed usage summary from pre-processor\n * @param snapshot - Environment snapshot from environment-scanner\n * @param config - Optional analysis configuration (defaults applied if omitted)\n * @param outcomeSummaries - Optional outcome summaries for confidence adjustment\n * @returns Validated AnalysisResult with sorted, capped recommendations\n */\nexport function analyze(\n summary: Summary,\n snapshot: EnvironmentSnapshot,\n config?: AnalysisConfig,\n outcomeSummaries?: OutcomeSummary[],\n): AnalysisResult {\n const mergedConfig = config ?? analysisConfigSchema.parse({});\n\n // Collect recommendations from all classifiers\n const recommendations: Recommendation[] = [];\n for (const classify of classifiers) {\n const results = classify(summary, snapshot, mergedConfig);\n recommendations.push(...results);\n }\n\n // Adjust confidence based on outcome history (if provided)\n const adjusted =\n outcomeSummaries && outcomeSummaries.length > 0\n ? adjustConfidence(recommendations, outcomeSummaries)\n : recommendations;\n\n // Sort by confidence tier, then by evidence count\n adjusted.sort(sortRecommendations);\n\n // Cap at max_recommendations\n const capped = adjusted.slice(0, mergedConfig.max_recommendations);\n\n // Compute patterns_evaluated as sum of all pattern source arrays\n const patternsEvaluated =\n summary.top_repeated_prompts.length +\n summary.long_prompts.length +\n summary.permission_patterns.length +\n summary.tool_frequency.length;\n\n return analysisResultSchema.parse({\n generated_at: new Date().toISOString(),\n summary_period: summary.period,\n recommendations: capped,\n metadata: {\n classifier_count: classifiers.length,\n patterns_evaluated: patternsEvaluated,\n environment_ecosystems: snapshot.detected_ecosystems,\n claude_code_version: snapshot.claude_code.version,\n },\n });\n}\n","// Outcome tracker: cross-references applied recommendations against\n// the current environment snapshot to determine whether changes persist.\n// Persists outcomes as JSONL and computes pattern-level summaries for\n// confidence adjustment in subsequent analysis runs.\n\nimport { readFile, appendFile } from 'node:fs/promises';\nimport { paths } from '../storage/dirs.js';\nimport { loadState } from '../delivery/state.js';\nimport {\n outcomeEntrySchema,\n type OutcomeEntry,\n type OutcomeSummary,\n} from '../schemas/onboarding.js';\nimport type { RecommendationStateEntry } from '../schemas/delivery.js';\nimport type { EnvironmentSnapshot } from './schemas.js';\n\n/**\n * Track outcomes for all applied recommendations by checking their\n * persistence in the current environment snapshot.\n *\n * For each applied recommendation:\n * 1. Check if the change still exists in the environment\n * 2. Determine outcome: positive (persisted 5+ checks), negative (reverted),\n * or monitoring (persisted but < 5 checks)\n * 3. Append outcome entry to JSONL history\n *\n * @param snapshot - Current environment snapshot\n * @returns Array of outcome entries for all applied recommendations\n */\nexport async function trackOutcomes(\n snapshot: EnvironmentSnapshot,\n): Promise<OutcomeEntry[]> {\n const state = await loadState();\n const applied = state.entries.filter((e) => e.status === 'applied');\n\n if (applied.length === 0) return [];\n\n const history = await loadOutcomeHistory();\n const results: OutcomeEntry[] = [];\n\n for (const entry of applied) {\n // Find most recent outcome for this recommendation\n const priorEntries = history.filter(\n (h) => h.recommendation_id === entry.id,\n );\n const latest = priorEntries.length > 0\n ? priorEntries[priorEntries.length - 1]\n : undefined;\n\n const checksCount = latest\n ? latest.checks_since_applied + 1\n : 1;\n\n const persisted = checkPersistence(entry, snapshot);\n\n // Determine outcome\n let outcome: 'positive' | 'negative' | 'monitoring';\n if (!persisted) {\n outcome = 'negative';\n } else if (checksCount >= 5) {\n outcome = 'positive';\n } else {\n outcome = 'monitoring';\n }\n\n // Infer pattern_type from the recommendation ID prefix\n const patternType = inferPatternType(entry.id);\n\n // Infer target from the recommendation ID prefix\n const target = inferTarget(entry.id);\n\n const outcomeEntry: OutcomeEntry = {\n recommendation_id: entry.id,\n pattern_type: patternType,\n target,\n applied_at: entry.updated_at,\n checked_at: new Date().toISOString(),\n persisted,\n checks_since_applied: checksCount,\n outcome,\n };\n\n results.push(outcomeEntry);\n await appendOutcome(outcomeEntry);\n }\n\n return results;\n}\n\n/**\n * Check whether an applied recommendation's change still persists\n * in the current environment.\n *\n * Detection heuristics by recommendation type:\n * - SETTINGS (allowedTools): check if tool exists in snapshot settings\n * - HOOK (rec-repeated-*): check if hooks exist in snapshot\n * - SKILL (rec-long-*): check if skills exist in snapshot\n * - RULE (rec-correction-*): check if rules exist in snapshot\n * - Default: assume persisted when persistence cannot be verified\n */\nfunction checkPersistence(\n entry: RecommendationStateEntry,\n snapshot: EnvironmentSnapshot,\n): boolean {\n // SETTINGS persistence: check allowedTools\n if (entry.applied_details) {\n const toolMatch = entry.applied_details.match(/Added (\\w+) to allowedTools/);\n if (toolMatch) {\n const toolName = toolMatch[1];\n const userSettings = snapshot.settings.user as Record<string, unknown> | null;\n if (!userSettings) return false;\n const allowedTools = userSettings.allowedTools;\n if (!Array.isArray(allowedTools)) return false;\n return allowedTools.includes(toolName);\n }\n }\n\n // HOOK persistence: rec-repeated-* prefix\n if (entry.id.startsWith('rec-repeated-')) {\n return snapshot.installed_tools.hooks.length > 0;\n }\n\n // SKILL persistence: rec-long-* prefix\n if (entry.id.startsWith('rec-long-')) {\n return snapshot.installed_tools.skills.length > 0;\n }\n\n // RULE persistence: rec-correction-* prefix\n if (entry.id.startsWith('rec-correction-')) {\n return snapshot.installed_tools.rules.length > 0;\n }\n\n // Default: assume persisted when we cannot verify\n return true;\n}\n\n/**\n * Append an outcome entry to the JSONL history file.\n */\nasync function appendOutcome(entry: OutcomeEntry): Promise<void> {\n await appendFile(\n paths.outcomeHistory,\n JSON.stringify(entry) + '\\n',\n 'utf-8',\n );\n}\n\n/**\n * Load outcome history from the JSONL file.\n * Returns empty array when the file does not exist.\n * Silently skips invalid or malformed lines.\n */\nexport async function loadOutcomeHistory(): Promise<OutcomeEntry[]> {\n let raw: string;\n try {\n raw = await readFile(paths.outcomeHistory, 'utf-8');\n } catch (err: unknown) {\n if (isNodeError(err) && err.code === 'ENOENT') {\n return [];\n }\n throw err;\n }\n\n const entries: OutcomeEntry[] = [];\n const lines = raw.split('\\n').filter((line) => line.trim().length > 0);\n\n for (const line of lines) {\n try {\n const parsed = JSON.parse(line);\n const result = outcomeEntrySchema.safeParse(parsed);\n if (result.success) {\n entries.push(result.data);\n }\n } catch {\n // Skip malformed JSON lines silently\n }\n }\n\n return entries;\n}\n\n/**\n * Compute outcome summaries grouped by pattern_type.\n * For each group: counts unique recommendation_ids, tallies positive\n * (persisted) and negative (reverted) outcomes, and computes\n * persistence_rate = persisted / total_applied.\n *\n * Uses the latest outcome per recommendation_id for determination.\n */\nexport function computeOutcomeSummaries(\n history: OutcomeEntry[],\n): OutcomeSummary[] {\n if (history.length === 0) return [];\n\n // Group by pattern_type\n const groups = new Map<string, OutcomeEntry[]>();\n for (const entry of history) {\n const group = groups.get(entry.pattern_type) ?? [];\n group.push(entry);\n groups.set(entry.pattern_type, group);\n }\n\n const summaries: OutcomeSummary[] = [];\n\n for (const [patternType, entries] of groups) {\n // Get the latest entry per recommendation_id\n const latestByRec = new Map<string, OutcomeEntry>();\n for (const entry of entries) {\n latestByRec.set(entry.recommendation_id, entry);\n }\n\n let totalPersisted = 0;\n let totalReverted = 0;\n\n for (const entry of latestByRec.values()) {\n if (entry.outcome === 'positive') {\n totalPersisted++;\n } else if (entry.outcome === 'negative') {\n totalReverted++;\n }\n // 'monitoring' entries don't count toward either\n }\n\n const totalApplied = latestByRec.size;\n const persistenceRate = totalApplied > 0\n ? totalPersisted / totalApplied\n : 0;\n\n summaries.push({\n pattern_type: patternType,\n total_applied: totalApplied,\n total_persisted: totalPersisted,\n total_reverted: totalReverted,\n persistence_rate: persistenceRate,\n });\n }\n\n return summaries;\n}\n\n/**\n * Infer the pattern type from a recommendation ID prefix.\n * Values must match the exact strings produced by each classifier.\n * For prefixes that map to multiple sub-types (ecosystem, onboarding),\n * the most common sub-type is returned as a best-effort default.\n */\nfunction inferPatternType(id: string): string {\n if (id.startsWith('rec-repeated-')) return 'repeated_prompt';\n if (id.startsWith('rec-long-')) return 'long_prompt';\n if (id.startsWith('rec-permission-always-approved-')) return 'permission-always-approved';\n if (id.startsWith('rec-correction-')) return 'code_correction';\n if (id.startsWith('rec-personal-')) return 'personal_info';\n if (id.startsWith('rec-drift-')) return 'config_drift';\n if (id.startsWith('rec-ecosystem-')) return 'version_update';\n if (id.startsWith('rec-onboarding-')) return 'onboarding_start_hooks';\n if (id.startsWith('rec-tool-preference-')) return 'tool-preference';\n return 'unknown';\n}\n\n/**\n * Infer the routing target from a recommendation ID prefix.\n * Covers all 8 classifier prefixes plus tool-preference.\n */\nfunction inferTarget(id: string): string {\n if (id.startsWith('rec-repeated-')) return 'HOOK';\n if (id.startsWith('rec-long-')) return 'SKILL';\n if (id.startsWith('rec-permission-always-approved-')) return 'SETTINGS';\n if (id.startsWith('rec-correction-')) return 'RULE';\n if (id.startsWith('rec-personal-')) return 'MEMORY';\n if (id.startsWith('rec-drift-')) return 'CLAUDE_MD';\n if (id.startsWith('rec-ecosystem-')) return 'CLAUDE_MD';\n if (id.startsWith('rec-tool-preference-')) return 'SETTINGS';\n if (id.startsWith('rec-onboarding-')) return 'HOOK';\n return 'MEMORY';\n}\n\n// Type guard for Node.js errors with code property\nfunction isNodeError(err: unknown): err is NodeJS.ErrnoException {\n return err instanceof Error && 'code' in err;\n}\n","// Recommendation state lifecycle management.\n// Tracks recommendation statuses (pending/applied/dismissed) in a JSON file\n// that survives across analysis re-runs and sessions.\n\nimport { readFile } from 'node:fs/promises';\nimport writeFileAtomic from 'write-file-atomic';\nimport { paths } from '../storage/dirs.js';\nimport {\n recommendationStateSchema,\n type RecommendationState,\n type RecommendationStatus,\n} from '../schemas/delivery.js';\n\n/**\n * Load the recommendation state from disk.\n * Returns an empty state when the file does not exist.\n */\nexport async function loadState(): Promise<RecommendationState> {\n try {\n const raw = await readFile(paths.recommendationState, 'utf-8');\n return recommendationStateSchema.parse(JSON.parse(raw));\n } catch (err: unknown) {\n // File not found or invalid JSON: return empty state\n if (isNodeError(err) && err.code === 'ENOENT') {\n return { entries: [], last_updated: new Date().toISOString() };\n }\n // Re-throw unexpected errors\n throw err;\n }\n}\n\n/**\n * Save the recommendation state atomically to disk.\n */\nexport async function saveState(state: RecommendationState): Promise<void> {\n await writeFileAtomic(\n paths.recommendationState,\n JSON.stringify(state, null, 2),\n );\n}\n\n/**\n * Update the status of a recommendation by ID.\n * Creates a new entry if the ID is not found.\n */\nexport async function updateStatus(\n id: string,\n status: RecommendationStatus,\n details?: string,\n): Promise<void> {\n const state = await loadState();\n const now = new Date().toISOString();\n\n const existing = state.entries.find((e) => e.id === id);\n if (existing) {\n existing.status = status;\n existing.updated_at = now;\n if (status === 'applied' && details !== undefined) {\n existing.applied_details = details;\n } else if (status !== 'applied') {\n // Clear applied_details when not in applied status\n existing.applied_details = undefined;\n }\n } else {\n state.entries.push({\n id,\n status,\n updated_at: now,\n ...(status === 'applied' && details !== undefined\n ? { applied_details: details }\n : {}),\n });\n }\n\n state.last_updated = now;\n await saveState(state);\n}\n\n/**\n * Get a Map of recommendation ID to status for quick lookups.\n */\nexport async function getStatusMap(): Promise<Map<string, RecommendationStatus>> {\n const state = await loadState();\n return new Map(state.entries.map((e) => [e.id, e.status]));\n}\n\n// Type guard for Node.js errors with code property\nfunction isNodeError(err: unknown): err is NodeJS.ErrnoException {\n return err instanceof Error && 'code' in err;\n}\n","// Delivery schemas for recommendation state tracking and auto-apply logging.\n// Defines: recommendation status lifecycle (pending/applied/dismissed),\n// state entries persisted in JSON, and auto-apply audit log entries.\n\nimport { z } from 'zod/v4';\n\nexport const recommendationStatusSchema = z.enum(['pending', 'applied', 'dismissed']);\nexport type RecommendationStatus = z.infer<typeof recommendationStatusSchema>;\n\nexport const recommendationStateEntrySchema = z.object({\n id: z.string(),\n status: recommendationStatusSchema,\n updated_at: z.iso.datetime(),\n applied_details: z.string().optional(),\n});\nexport type RecommendationStateEntry = z.infer<typeof recommendationStateEntrySchema>;\n\nexport const recommendationStateSchema = z.object({\n entries: z.array(recommendationStateEntrySchema),\n last_updated: z.iso.datetime(),\n});\nexport type RecommendationState = z.infer<typeof recommendationStateSchema>;\n\nexport const autoApplyLogEntrySchema = z.object({\n timestamp: z.iso.datetime(),\n recommendation_id: z.string(),\n target: z.string(),\n action: z.string(),\n success: z.boolean(),\n details: z.string().optional(),\n backup_path: z.string().optional(),\n});\nexport type AutoApplyLogEntry = z.infer<typeof autoApplyLogEntrySchema>;\n","// Phase 6 schemas for onboarding detection and outcome tracking.\n// Defines: experience tier classification, experience level with score\n// breakdown, outcome tracking entries, and outcome summary aggregation.\n\nimport { z } from 'zod/v4';\n\n// Experience level types\nexport const experienceTierSchema = z.enum(['newcomer', 'intermediate', 'power_user']);\nexport type ExperienceTier = z.infer<typeof experienceTierSchema>;\n\nexport const experienceLevelSchema = z.object({\n tier: experienceTierSchema,\n score: z.number().min(0).max(100),\n breakdown: z.object({\n hooks: z.number(),\n rules: z.number(),\n skills: z.number(),\n plugins: z.number(),\n claude_md: z.number(),\n ecosystems: z.number(),\n }),\n});\nexport type ExperienceLevel = z.infer<typeof experienceLevelSchema>;\n\n// Outcome tracking types (used by Plan 02)\nexport const outcomeEntrySchema = z.object({\n recommendation_id: z.string(),\n pattern_type: z.string(),\n target: z.string(),\n applied_at: z.iso.datetime(),\n checked_at: z.iso.datetime(),\n persisted: z.boolean(),\n checks_since_applied: z.number(),\n outcome: z.enum(['positive', 'negative', 'monitoring']),\n});\nexport type OutcomeEntry = z.infer<typeof outcomeEntrySchema>;\n\nexport const outcomeSummarySchema = z.object({\n pattern_type: z.string(),\n total_applied: z.number(),\n total_persisted: z.number(),\n total_reverted: z.number(),\n persistence_rate: z.number(),\n});\nexport type OutcomeSummary = z.infer<typeof outcomeSummarySchema>;\n","// Threshold trigger: orchestrates analysis when counter reaches the configured\n// threshold. Respects cooldown period, resets counter after success, preserves\n// counter on failure for automatic retry at next threshold check.\n\nimport { readCounter } from '../storage/counter.js';\nimport { loadConfig } from '../storage/config.js';\nimport { paths, ensureInit } from '../storage/dirs.js';\nimport { preProcess } from './pre-processor.js';\nimport { scanEnvironment } from './environment-scanner.js';\nimport { analyze } from './analyzer.js';\nimport {\n trackOutcomes,\n loadOutcomeHistory,\n computeOutcomeSummaries,\n} from './outcome-tracker.js';\nimport type { OutcomeSummary } from '../schemas/onboarding.js';\nimport type { AnalysisResult } from '../schemas/recommendation.js';\nimport writeFileAtomic from 'write-file-atomic';\nimport { readFile } from 'node:fs/promises';\nimport { lock } from 'proper-lockfile';\n\n// Cooldown period: prevent re-triggering analysis within 60 seconds of last run\nconst COOLDOWN_MS = 60_000;\n\n/**\n * Write an AnalysisResult to the analysis-result.json path atomically.\n */\nexport async function writeAnalysisResult(\n result: AnalysisResult,\n): Promise<void> {\n await ensureInit();\n await writeFileAtomic(paths.analysisResult, JSON.stringify(result, null, 2));\n}\n\n/**\n * Run the full analysis pipeline: preProcess -> scanEnvironment -> analyze -> write.\n *\n * @param cwd - Current working directory for environment scanning\n * @returns The generated AnalysisResult\n */\nexport async function runAnalysis(cwd: string): Promise<AnalysisResult> {\n const summary = await preProcess();\n const snapshot = await scanEnvironment(cwd);\n\n // Wire outcome tracking: track current state, compute summaries for confidence adjustment (QUA-04)\n let outcomeSummaries: OutcomeSummary[] | undefined;\n try {\n await trackOutcomes(snapshot);\n const history = await loadOutcomeHistory();\n outcomeSummaries = computeOutcomeSummaries(history);\n } catch {\n // Outcome tracking failure must not block analysis\n }\n\n const result = analyze(summary, snapshot, undefined, outcomeSummaries);\n await writeAnalysisResult(result);\n return result;\n}\n\n/**\n * Reset the counter with a last_analysis timestamp atomically.\n * Uses proper-lockfile for cross-process safety.\n */\nasync function resetCounterWithTimestamp(): Promise<void> {\n // Ensure counter file exists before locking\n try {\n await readFile(paths.counter, 'utf-8');\n } catch {\n const initial = {\n total: 0,\n session: {},\n last_updated: new Date().toISOString(),\n };\n await writeFileAtomic(paths.counter, JSON.stringify(initial, null, 2));\n }\n\n const release = await lock(paths.counter, {\n retries: { retries: 50, minTimeout: 20, maxTimeout: 1000, randomize: true },\n stale: 10000,\n });\n\n try {\n const now = new Date().toISOString();\n const data = {\n total: 0,\n session: {},\n last_analysis: now,\n last_updated: now,\n };\n await writeFileAtomic(paths.counter, JSON.stringify(data, null, 2));\n } finally {\n await release();\n }\n}\n\n/**\n * Check if analysis should be triggered and run it if conditions are met.\n *\n * Conditions:\n * 1. analysis.enabled is true in config\n * 2. counter.total >= config.analysis.threshold\n * 3. Not within cooldown period since last_analysis\n *\n * On success: resets counter and records last_analysis timestamp.\n * On failure: preserves counter data for retry at next check.\n *\n * @param cwd - Current working directory\n * @returns true if analysis was triggered, false otherwise\n */\nexport async function checkAndTriggerAnalysis(\n cwd: string,\n): Promise<boolean> {\n const config = await loadConfig();\n if (!config.analysis.enabled) return false;\n\n const counter = await readCounter();\n if (counter.total < config.analysis.threshold) return false;\n\n // Check cooldown\n if (counter.last_analysis) {\n const elapsed = Date.now() - new Date(counter.last_analysis).getTime();\n if (elapsed < COOLDOWN_MS) return false;\n }\n\n // Attempt analysis -- preserve counter on failure\n try {\n await runAnalysis(cwd);\n } catch {\n return false;\n }\n\n // Reset counter with timestamp after successful analysis\n await resetCounterWithTimestamp();\n return true;\n}\n","// Shared utilities for hook handlers: stdin reading and tool input summarization\n\nconst MAX_LEN = 200;\n\n/**\n * Truncate a string to maxLen characters, appending '...' if truncated.\n */\nfunction truncate(str: string, maxLen: number): string {\n return str.length > maxLen ? str.slice(0, maxLen) + '...' : str;\n}\n\n/**\n * Read all data from a readable stream into a string buffer.\n * Used for testability -- readStdin() delegates to this with process.stdin.\n */\nexport function readFromStream(stream: NodeJS.ReadableStream): Promise<string> {\n return new Promise((resolve, reject) => {\n let data = '';\n stream.setEncoding('utf-8');\n stream.on('data', (chunk: string) => {\n data += chunk;\n });\n stream.on('end', () => resolve(data));\n stream.on('error', reject);\n });\n}\n\n/**\n * Read all stdin data into a string buffer.\n * Claude Code pipes JSON to hook stdin; this collects all chunks before parsing.\n */\nexport function readStdin(): Promise<string> {\n return readFromStream(process.stdin);\n}\n\n/**\n * Produce a concise summary of tool_input, capped at 200 characters.\n * Prevents Write/Edit tool inputs (with full file content) from bloating logs.\n */\nexport function summarizeToolInput(\n toolName: string,\n toolInput: Record<string, unknown>,\n): string {\n switch (toolName) {\n case 'Bash':\n return truncate(String(toolInput.command ?? ''), MAX_LEN);\n case 'Write':\n case 'Edit':\n case 'Read':\n return truncate(String(toolInput.file_path ?? ''), MAX_LEN);\n case 'Glob':\n return truncate(String(toolInput.pattern ?? ''), MAX_LEN);\n case 'Grep':\n return truncate(String(toolInput.pattern ?? ''), MAX_LEN);\n default: {\n // MCP tools and others: stringify then truncate\n const str = JSON.stringify(toolInput);\n return truncate(str, MAX_LEN);\n }\n }\n}\n","// Stop hook handler: triggers analysis when interaction counter reaches threshold.\n// Invoked by Claude Code after each response completes.\n// Reads JSON from stdin, validates, checks threshold, runs analysis if needed.\n\nimport { stopInputSchema } from '../schemas/hook-input.js';\nimport { checkAndTriggerAnalysis } from '../analysis/trigger.js';\nimport { readStdin } from './shared.js';\n\n/**\n * Core handler logic, exported for testability.\n * Validates input, guards against infinite loops, triggers analysis.\n * Swallows all errors to never block Claude Code.\n */\nexport async function handleStop(rawJson: string): Promise<void> {\n try {\n const input = stopInputSchema.parse(JSON.parse(rawJson));\n\n // Prevent infinite loop: if this hook invocation was triggered\n // by a Stop hook agent, do not re-trigger analysis\n if (input.stop_hook_active) return;\n\n await checkAndTriggerAnalysis(input.cwd);\n } catch {\n // Never block Claude Code\n }\n}\n\n// Entry point when invoked by Claude Code as a command hook\nasync function main(): Promise<void> {\n try {\n const raw = await readStdin();\n await handleStop(raw);\n } catch {\n // Never block Claude Code\n }\n process.exit(0);\n}\n\nmain();\n"],"mappings":"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","names":["z","readFile","writeFileAtomic","z","readFile","writeFileAtomic","join","z","z","writeFileAtomic","formatDate","readdir","readFile","join","writeFileAtomic","join","writeFileAtomic","readFile","readdir","z","readFile","readFile","writeFileAtomic","z","readFile","z","readFile","isNodeError","writeFileAtomic","readFile","lock"]}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Core handler logic, exported for testability.
|
|
3
|
+
* Validates input, appends prompt log entry, increments counter.
|
|
4
|
+
* Swallows all errors to never block Claude Code.
|
|
5
|
+
*/
|
|
6
|
+
declare function handleUserPromptSubmit(rawJson: string): Promise<void>;
|
|
7
|
+
|
|
8
|
+
export { handleUserPromptSubmit };
|