import type { StudioSession } from '../../domain/types' import { logPlotStudioSkillTrace } from '../../observability/plot-studio-skill-trace' import { createStudioSkillRegistry, type StudioSkillRegistry } from '../registry/skill-registry' import { createStudioSkillLoader } from '../resolver/skill-loader' import type { StudioResolvedSkill, StudioSkillDiscoveryEntry, StudioSkillUsageSummary } from '../schema/skill-types' import { createInMemoryStudioSkillStateStore, type StudioSkillStateStore } from '../state/skill-state-store' export interface StudioSkillRuntime { listDiscovery(session: StudioSession): Promise resolve(name: string, session: StudioSession): Promise listSummaries(session: StudioSession): Promise recordUsage(input: { session: StudioSession skillName: string reason?: string takeaway?: string stillRelevant?: boolean }): Promise } export function createStudioSkillRuntime(input?: { registry?: StudioSkillRegistry stateStore?: StudioSkillStateStore maxFiles?: number }): StudioSkillRuntime { const registry = input?.registry ?? createStudioSkillRegistry() const loader = createStudioSkillLoader({ registry, maxFiles: input?.maxFiles }) const stateStore = input?.stateStore ?? createInMemoryStudioSkillStateStore() return { async listDiscovery(session) { logPlotStudioSkillTrace(session.studioKind, 'skill.discovery.requested', { sessionId: session.id, sessionDirectory: session.directory, }) const entries = await registry.list(session) logPlotStudioSkillTrace(session.studioKind, 'skill.discovery.completed', { sessionId: session.id, discoveredSkillCount: entries.length, discoveredSkillNames: entries.map((entry) => entry.name), }) return entries }, async resolve(name, session) { logPlotStudioSkillTrace(session.studioKind, 'skill.resolve.requested', { sessionId: session.id, skillName: name, }) const skill = await loader.resolve(name, session) logPlotStudioSkillTrace(session.studioKind, 'skill.resolve.completed', { sessionId: session.id, skillName: skill.name, source: skill.source, scope: skill.scope, entryFile: skill.entryFile, fileCount: skill.files.length, }) return skill }, async listSummaries(session) { logPlotStudioSkillTrace(session.studioKind, 'skill.summary.requested', { sessionId: session.id, }) const summaries = await stateStore.list(session) logPlotStudioSkillTrace(session.studioKind, 'skill.summary.completed', { sessionId: session.id, summaryCount: summaries.length, summarySkillNames: summaries.map((summary) => summary.skillName), }) return summaries }, async recordUsage(value) { await stateStore.record(value) logPlotStudioSkillTrace(value.session.studioKind, 'skill.usage.recorded', { sessionId: value.session.id, skillName: value.skillName, reason: value.reason, takeaway: value.takeaway, stillRelevant: value.stillRelevant, }) } } }