/** * Condition Registry for Dynamic Prompt Fragments * * Each key matches a fragment ID in prompt-fragments.json. * The function returns: * - false → fragment is skipped * - true → fragment is applied as-is * - Record → fragment is applied with {{variable}} interpolation * * See DYNAMIC-PROMPTS.md for how to add new conditions. */ import fs from 'fs'; import { WORKSPACE_DIR } from '../../shared/paths.js'; import { loadConfig } from '../../shared/config.js'; import path from 'path'; export type ConditionResult = false | true | Record; export const conditions: Record Promise> = { /** * Shell mode: the workspace renders inside a same-origin iframe under the * supervisor's shell page. BLOBY_NO_SHELL=1 is the kill switch back to * legacy top-level serving — the iframe note must disappear with it. */ 'workspace-iframe-shell': async () => { return process.env.BLOBY_NO_SHELL !== '1'; }, /** * Official Workspace Lock is active. * Calls GET http://localhost:{backendPort}/api/lock/status * Returns { configured: true, type: "pin"|"password" } when locked. */ 'workspace-lock-official': async () => { try { const cfg = loadConfig(); const backendPort = cfg.port + 4; const res = await fetch(`http://localhost:${backendPort}/api/lock/status`, { signal: AbortSignal.timeout(2000), }); if (!res.ok) return false; const data = await res.json() as { configured: boolean; type: string | null }; if (data.configured && data.type) { return { lockType: data.type }; } return false; } catch { // Backend not running or endpoint doesn't exist return false; } }, /** * Custom workspace lock: the lock endpoint doesn't exist (not the official blueprint) * AND MEMORY.md contains CUSTOM_WORKSPACE_LOCK=true. */ 'workspace-lock-custom': async () => { try { // First verify the official lock endpoint is NOT available const cfg = loadConfig(); const backendPort = cfg.port + 4; const res = await fetch(`http://localhost:${backendPort}/api/lock/status`, { signal: AbortSignal.timeout(2000), }); // If the endpoint exists and returns OK, this isn't a custom lock if (res.ok) return false; } catch { // Endpoint doesn't exist — that's expected for custom lock, continue checking } // Check MEMORY.md for the flag try { const memoryPath = path.join(WORKSPACE_DIR, 'MEMORY.md'); const content = fs.readFileSync(memoryPath, 'utf-8'); if (content.includes('CUSTOM_WORKSPACE_LOCK=true')) { return true; } } catch {} return false; }, /** * No workspace lock at all — fallback. Always true. * (Lowest priority, so it only fires if the others don't match.) */ 'workspace-lock-none': async () => { return true; }, };