Files
memind/scripts/memind-runtime-profile.mjs

120 lines
4.1 KiB
JavaScript

import fs from 'node:fs';
import path from 'node:path';
export const MEMIND_RUNTIME_PROFILES = new Set(['local', 'split-service', 'production']);
/**
* Load Memind env files in standard order. Later files only fill unset keys.
*/
export function loadMemindEnvFiles(rootDir, env = process.env) {
const root = path.resolve(rootDir);
for (const relativePath of ['../../.env.local', '.env']) {
loadEnvFile(path.join(root, relativePath), env);
}
}
function loadEnvFile(filePath, env = process.env) {
if (!fs.existsSync(filePath)) return;
for (const line of fs.readFileSync(filePath, 'utf8').split('\n')) {
const trimmed = line.trim();
if (!trimmed || trimmed.startsWith('#')) continue;
const separator = trimmed.indexOf('=');
if (separator < 0) continue;
const key = trimmed.slice(0, separator).trim();
const value = trimmed.slice(separator + 1).trim();
if (!env[key]) env[key] = value;
}
}
function expandEnvReference(value, env = process.env) {
const raw = String(value ?? '').trim();
const match = raw.match(/^\$\{([A-Z0-9_]+)\}$/);
if (!match) return raw;
return String(env[match[1]] ?? '').trim() || raw;
}
export function resolveMemindRuntimeProfile(env = process.env) {
const explicit = String(env.MEMIND_RUNTIME_PROFILE ?? '').trim().toLowerCase();
if (explicit) {
if (!MEMIND_RUNTIME_PROFILES.has(explicit)) {
throw new Error(
`Unsupported MEMIND_RUNTIME_PROFILE "${explicit}". Expected: ${[...MEMIND_RUNTIME_PROFILES].join(', ')}`,
);
}
return explicit;
}
if (String(env.NODE_ENV ?? '').trim().toLowerCase() === 'production') {
return 'production';
}
return 'local';
}
/**
* Apply environment-specific defaults after .env files are loaded.
*
* - local: monolith MindSpace adapter, repo-local storage (pnpm dev default)
* - split-service: remote adapter against standalone MindSpace on 8082
* - production: no overrides; 103 .env is source of truth
*/
export function applyMemindRuntimeProfile({
rootDir = process.cwd(),
env = process.env,
profile,
} = {}) {
const resolvedProfile = profile ?? resolveMemindRuntimeProfile(env);
env.MEMIND_RUNTIME_PROFILE = resolvedProfile;
if (resolvedProfile === 'local') {
env.MINDSPACE_SERVER_ADAPTER = 'local';
if (!env.MINDSPACE_STORAGE_ROOT) {
env.MINDSPACE_STORAGE_ROOT = path.join(path.resolve(rootDir), 'data', 'mindspace');
}
return {
profile: resolvedProfile,
mindspaceAdapter: 'local',
storageRoot: env.MINDSPACE_STORAGE_ROOT,
};
}
if (resolvedProfile === 'split-service') {
env.MINDSPACE_SERVER_ADAPTER = 'remote';
env.MINDSPACE_REMOTE_BASE_URL = String(
env.MINDSPACE_REMOTE_BASE_URL ?? 'http://127.0.0.1:8082',
).trim();
const expandedToken = expandEnvReference(env.MINDSPACE_REMOTE_AUTH_TOKEN, env);
if (expandedToken) {
env.MINDSPACE_REMOTE_AUTH_TOKEN = expandedToken;
} else if (env.TKMIND_SERVER__SECRET_KEY) {
env.MINDSPACE_REMOTE_AUTH_TOKEN = String(env.TKMIND_SERVER__SECRET_KEY).trim();
}
if (!env.MINDSPACE_STORAGE_ROOT) {
env.MINDSPACE_STORAGE_ROOT = '/Users/john/MindSpace/data/mindspace';
}
return {
profile: resolvedProfile,
mindspaceAdapter: 'remote',
remoteBaseUrl: env.MINDSPACE_REMOTE_BASE_URL,
storageRoot: env.MINDSPACE_STORAGE_ROOT,
};
}
return {
profile: resolvedProfile,
mindspaceAdapter: String(env.MINDSPACE_SERVER_ADAPTER ?? 'local').trim().toLowerCase() || 'local',
storageRoot: env.MINDSPACE_STORAGE_ROOT ?? null,
};
}
export function describeMemindRuntimeProfile(env = process.env) {
const profile = resolveMemindRuntimeProfile(env);
const adapter = String(env.MINDSPACE_SERVER_ADAPTER ?? 'local').trim().toLowerCase() || 'local';
const parts = [`MEMIND_RUNTIME_PROFILE=${profile}`, `MINDSPACE_SERVER_ADAPTER=${adapter}`];
if (adapter === 'remote') {
parts.push(`MINDSPACE_REMOTE_BASE_URL=${env.MINDSPACE_REMOTE_BASE_URL ?? '(unset)'}`);
}
if (env.MINDSPACE_STORAGE_ROOT) {
parts.push(`MINDSPACE_STORAGE_ROOT=${env.MINDSPACE_STORAGE_ROOT}`);
}
return parts.join(', ');
}