const FILE_VERSION = 1; const MAX_PROMPT_TEXT_LENGTH = 200_000; const PROMPT_ID_PATTERN = /^[a-z0-9._-]{1,160}$/; const isVisiblePromptID = (id) => typeof id === 'string' && id.endsWith('.visible'); const hasOwn = (input, key) => Object.prototype.hasOwnProperty.call(input, key); const sanitizeOverrides = (value) => { if (!value || typeof value !== 'object' || Array.isArray(value)) { return {}; } const next = {}; for (const [key, entry] of Object.entries(value)) { if (!PROMPT_ID_PATTERN.test(key) || typeof entry !== 'string') { continue; } next[key] = entry; } return next; }; export const createMagicPromptRuntime = (dependencies) => { const { fsPromises, path, filePath, } = dependencies; let writeLock = Promise.resolve(); const readPromptState = async () => { try { const raw = await fsPromises.readFile(filePath, 'utf8'); const parsed = JSON.parse(raw); const overrides = sanitizeOverrides(parsed?.overrides); return { version: FILE_VERSION, overrides, }; } catch (error) { if (error && typeof error === 'object' && error.code === 'ENOENT') { return { version: FILE_VERSION, overrides: {} }; } console.warn('Failed to read magic prompts file:', error); return { version: FILE_VERSION, overrides: {} }; } }; const writePromptState = async (state) => { await fsPromises.mkdir(path.dirname(filePath), { recursive: true }); await fsPromises.writeFile(filePath, JSON.stringify(state, null, 2), 'utf8'); }; const persist = async (mutator) => { const run = async () => { const current = await readPromptState(); const next = await mutator(current); await writePromptState(next); return next; }; writeLock = writeLock.then(run, run); return writeLock; }; const setOverride = async (id, text) => { const normalizedId = typeof id === 'string' ? id.trim() : ''; if (!PROMPT_ID_PATTERN.test(normalizedId)) { throw new Error('Invalid prompt id'); } if (typeof text !== 'string') { throw new Error('Prompt text must be a string'); } if (isVisiblePromptID(normalizedId) && text.trim().length === 0) { throw new Error('Visible prompt text cannot be empty'); } if (text.length > MAX_PROMPT_TEXT_LENGTH) { throw new Error('Prompt text is too long'); } return persist(async (state) => { const nextOverrides = { ...state.overrides, [normalizedId]: text }; return { version: FILE_VERSION, overrides: nextOverrides, }; }); }; const resetOverride = async (id) => { const normalizedId = typeof id === 'string' ? id.trim() : ''; if (!PROMPT_ID_PATTERN.test(normalizedId)) { throw new Error('Invalid prompt id'); } return persist(async (state) => { if (!hasOwn(state.overrides, normalizedId)) { return state; } const nextOverrides = { ...state.overrides }; delete nextOverrides[normalizedId]; return { version: FILE_VERSION, overrides: nextOverrides, }; }); }; const resetAllOverrides = async () => { return persist(async () => ({ version: FILE_VERSION, overrides: {} })); }; return { readPromptState, setOverride, resetOverride, resetAllOverrides, }; };