Jake Shore 96e52666c5 MCPEngine full sync — studio scaffold, factory v2, server updates, state.json — 2026-02-12
=== NEW ===
- studio/ — MCPEngine Studio scaffold (Next.js monorepo, build plan)
- docs/FACTORY-V2.md — Factory v2 architecture doc
- docs/CALENDLY_MCP_BUILD_SUMMARY.md — Calendly MCP build report

=== UPDATED SERVERS ===
- fieldedge: Added jobs-tools, UI build script, main entry update
- lightspeed: Updated main + server entry points
- squarespace: Added collection-browser + page-manager apps
- toast: Added main + server entry points

=== INFRA ===
- infra/command-center/state.json — Updated pipeline state
- infra/command-center/FACTORY-V2.md — Factory v2 operator playbook
2026-02-12 17:58:33 -05:00

79 lines
2.0 KiB
TypeScript

// Skill Loader — reads .md skill files from skills/data/, caches in memory
import { readFileSync } from 'fs';
import { join } from 'path';
import { SKILL_REGISTRY, type SkillName } from './registry';
const SKILLS_DIR = join(__dirname, 'data');
// In-memory cache: filename → content
const fileCache = new Map<string, string>();
// Combined skill cache: skill name → concatenated content
const skillCache = new Map<string, string>();
function loadFile(filename: string): string {
const cached = fileCache.get(filename);
if (cached) return cached;
const filePath = join(SKILLS_DIR, filename);
const content = readFileSync(filePath, 'utf-8');
fileCache.set(filename, content);
return content;
}
/**
* Get the combined skill content for a named skill.
* Multi-file skills (builder, designer) are concatenated with separators.
*/
export function getSkill(name: string): string {
const cached = skillCache.get(name);
if (cached) return cached;
const mapping = SKILL_REGISTRY[name as SkillName];
if (!mapping) {
throw new Error(
`Unknown skill "${name}". Available: ${Object.keys(SKILL_REGISTRY).join(', ')}`
);
}
const parts = mapping.files.map((file) => {
const content = loadFile(file);
return `<!-- SKILL: ${file} -->\n${content}`;
});
const combined = parts.join('\n\n---\n\n');
skillCache.set(name, combined);
return combined;
}
/**
* Get a single raw skill file by filename.
*/
export function getSkillFile(filename: string): string {
return loadFile(filename);
}
/**
* Preload all skill files into cache. Call at startup for faster first requests.
*/
export function preloadSkills(): void {
for (const mapping of Object.values(SKILL_REGISTRY)) {
for (const file of mapping.files) {
loadFile(file);
}
}
// Also build combined caches
for (const name of Object.keys(SKILL_REGISTRY)) {
getSkill(name);
}
}
/**
* Clear all caches. Useful for development hot-reload.
*/
export function clearSkillCache(): void {
fileCache.clear();
skillCache.clear();
}