UNPKG

mlld

Version:

mlld: a modular prompt scripting language

721 lines (718 loc) 20.6 kB
import { ResolverError, ResolverErrorCode } from './chunk-YMCO2JI3.mjs'; import { __name, __publicField } from './chunk-OMKLS24H.mjs'; import * as os from 'os'; import * as path from 'path'; // core/resolvers/builtin/NowResolver.ts var _NowResolver = class _NowResolver { constructor() { __publicField(this, "name", "now"); __publicField(this, "description", "Provides current timestamp"); __publicField(this, "type", "input"); __publicField(this, "capabilities", { io: { read: true, write: false, list: false }, contexts: { import: true, path: true, output: false }, supportedContentTypes: [ "text", "data" ], defaultContentType: "text", priority: 1, cache: { strategy: "none" } // now is always computed fresh }); } canResolve(ref) { const cleanRef = ref.replace(/^@/, ""); return cleanRef === "now"; } async resolve(ref, config) { const currentTime = this.getMockedTime() || /* @__PURE__ */ new Date(); if (!config?.context || config.context === "variable" || config.context === "path") { return { content: currentTime.toISOString(), contentType: "text", metadata: { source: "now", timestamp: currentTime } }; } if (config.context === "import") { const exports = {}; const requestedImports = config.requestedImports || []; if (requestedImports.length === 0) { exports.iso = currentTime.toISOString(); exports.unix = Math.floor(currentTime.getTime() / 1e3).toString(); exports.date = currentTime.toISOString().split("T")[0]; exports.time = currentTime.toTimeString().split(" ")[0]; } else { for (const importName of requestedImports) { if (importName === "iso") { exports[importName] = currentTime.toISOString(); } else if (importName === "unix") { exports[importName] = Math.floor(currentTime.getTime() / 1e3).toString(); } else if (importName === "date") { exports[importName] = currentTime.toISOString().split("T")[0]; } else if (importName === "time") { exports[importName] = currentTime.toTimeString().split(" ")[0]; } else { exports[importName] = currentTime.toISOString(); } } } return { content: JSON.stringify(exports), contentType: "data", metadata: { source: "now", timestamp: currentTime } }; } throw new ResolverError("NOW resolver only supports variable and import contexts", ResolverErrorCode.UNSUPPORTED_CONTEXT, { resolverName: this.name, context: config?.context, operation: "resolve" }); } /** * Get mocked time for testing */ getMockedTime() { if (process.env.MLLD_MOCK_TIME) { if (/^\d+$/.test(process.env.MLLD_MOCK_TIME)) { return new Date(parseInt(process.env.MLLD_MOCK_TIME) * 1e3); } return new Date(process.env.MLLD_MOCK_TIME); } return null; } /** * Get default value for when NOW is used as a variable * This handles the mock time logic for tests */ getDefaultValue() { const currentTime = this.getMockedTime() || /* @__PURE__ */ new Date(); return currentTime.toISOString(); } }; __name(_NowResolver, "NowResolver"); var NowResolver = _NowResolver; var _DebugResolver = class _DebugResolver { constructor() { __publicField(this, "name", "debug"); __publicField(this, "description", "Provides environment and debug information"); __publicField(this, "type", "input"); __publicField(this, "capabilities", { io: { read: true, write: false, list: false }, contexts: { import: true, path: false, output: false }, supportedContentTypes: [ "data", "text" ], defaultContentType: "data", priority: 1, cache: { strategy: "none" } // debug info should be fresh }); } canResolve(ref) { const cleanRef = ref.replace(/^@/, ""); return cleanRef === "debug" || cleanRef.startsWith("debug/"); } async resolve(ref, config) { if (!config?.context || config.context === "variable") { const info = await this.collectDebugInfo(); return { content: JSON.stringify(info), contentType: "data", metadata: { source: "debug", timestamp: /* @__PURE__ */ new Date() } }; } if (config.context === "import") { const info = await this.collectDebugInfo(); const exports = {}; const imports = config.requestedImports || [ "json", "reduced", "markdown" ]; for (const importName of imports) { switch (importName) { case "environment": exports.environment = info.environment; break; case "system": exports.system = info.system; break; case "process": exports.process = info.process; break; case "mlld": exports.mlld = info.mlld; break; case "full": exports.full = info; break; case "json": exports.json = JSON.stringify(info, null, 2); break; case "reduced": exports.reduced = JSON.stringify({ environment: info.environment, version: info.mlld.version }); break; case "summary": exports.summary = this.formatSummary(info); break; case "markdown": exports.markdown = this.formatMarkdown(info); break; default: const value = this.getNestedValue(info, importName); if (value !== void 0) { exports[importName] = value; } } } return { content: JSON.stringify(exports), contentType: "data", metadata: { source: "debug", timestamp: /* @__PURE__ */ new Date() } }; } throw new ResolverError("DEBUG resolver only supports variable and import contexts", ResolverErrorCode.UNSUPPORTED_CONTEXT, { resolverName: this.name, context: config?.context, operation: "resolve" }); } /** * Generate debug information in requested format */ async generateDebugInfo(format) { const info = await this.collectDebugInfo(); switch (format.toLowerCase()) { case "summary": return this.formatSummary(info); case "markdown": return this.formatMarkdown(info); case "json": return JSON.stringify(info, null, 2); case "full": default: return this.formatFull(info); } } /** * Collect all debug information */ async collectDebugInfo() { const cwd = process.cwd?.() || "/"; const projectPath = await this.findProjectRoot(cwd); const time = this.getMockedTime() || /* @__PURE__ */ new Date(); const version = await this.getMlldVersion(); return { timestamp: time.toISOString(), version, mlld: { version, configFile: await this.findConfigFile(projectPath || cwd) }, project: { basePath: projectPath || cwd, configFile: await this.findConfigFile(projectPath || cwd) }, environment: { cwd, projectPath, nodeVersion: process.version || "unknown", platform: process.platform || "unknown", arch: process.arch || "unknown", user: os.userInfo().username, hostname: os.hostname() }, system: { cpus: os.cpus().length, memory: { total: os.totalmem(), free: os.freemem(), used: os.totalmem() - os.freemem() }, uptime: os.uptime(), loadAvg: os.loadavg() }, process: { pid: process.pid || 0, ppid: process.ppid || 0, argv: process.argv || [], execPath: process.execPath || "", memoryUsage: process.memoryUsage?.() || {} }, env: this.getFilteredEnv() }; } /** * Format as summary (key info only) */ formatSummary(info) { return [ `MLLD Debug Summary`, `==================`, `Time: ${info.timestamp}`, `Version: ${info.mlld.version}`, `Platform: ${info.environment.platform} (${info.environment.arch})`, `Node: ${info.environment.nodeVersion}`, `CWD: ${info.environment.cwd}`, `Project: ${info.environment.projectPath || "Not found"}`, `Memory: ${this.formatBytes(info.system.memory.used)} / ${this.formatBytes(info.system.memory.total)}` ].join("\n"); } /** * Format as markdown */ formatMarkdown(info) { return [ `# MLLD Debug Information`, ``, `## Environment`, `- **Time**: ${info.timestamp}`, `- **MLLD Version**: ${info.mlld.version}`, `- **Platform**: ${info.environment.platform} (${info.environment.arch})`, `- **Node Version**: ${info.environment.nodeVersion}`, `- **Current Directory**: \`${info.environment.cwd}\``, `- **Project Root**: \`${info.environment.projectPath || "Not found"}\``, ``, `## System`, `- **CPUs**: ${info.system.cpus}`, `- **Memory**: ${this.formatBytes(info.system.memory.used)} / ${this.formatBytes(info.system.memory.total)}`, `- **System Uptime**: ${this.formatDuration(info.system.uptime)}`, ``, `## Process`, `- **PID**: ${info.process.pid}`, `- **Memory Usage**:`, ` - Heap: ${this.formatBytes(info.process.memoryUsage.heapUsed)} / ${this.formatBytes(info.process.memoryUsage.heapTotal)}`, ` - RSS: ${this.formatBytes(info.process.memoryUsage.rss)}`, ` - External: ${this.formatBytes(info.process.memoryUsage.external)}` ].join("\n"); } /** * Format as full text output */ formatFull(info) { const sections = []; sections.push([ `MLLD Debug Information`, `======================`, `Generated: ${info.timestamp}`, `` ].join("\n")); sections.push([ `MLLD:`, ` Version: ${info.mlld.version}`, ` Config: ${info.mlld.configFile || "Not found"}`, `` ].join("\n")); sections.push([ `Environment:`, ` Current Directory: ${info.environment.cwd}`, ` Project Root: ${info.environment.projectPath || "Not found"}`, ` Node Version: ${info.environment.nodeVersion}`, ` Platform: ${info.environment.platform} (${info.environment.arch})`, ` User: ${info.environment.user}`, ` Hostname: ${info.environment.hostname}`, `` ].join("\n")); sections.push([ `System:`, ` CPUs: ${info.system.cpus}`, ` Memory:`, ` Total: ${this.formatBytes(info.system.memory.total)}`, ` Free: ${this.formatBytes(info.system.memory.free)}`, ` Used: ${this.formatBytes(info.system.memory.used)}`, ` Uptime: ${this.formatDuration(info.system.uptime)}`, ` Load Average: ${info.system.loadAvg.map((n) => n.toFixed(2)).join(", ")}`, `` ].join("\n")); sections.push([ `Process:`, ` PID: ${info.process.pid}`, ` Parent PID: ${info.process.ppid}`, ` Executable: ${info.process.execPath}`, ` Memory Usage:`, ` RSS: ${this.formatBytes(info.process.memoryUsage.rss)}`, ` Heap Total: ${this.formatBytes(info.process.memoryUsage.heapTotal)}`, ` Heap Used: ${this.formatBytes(info.process.memoryUsage.heapUsed)}`, ` External: ${this.formatBytes(info.process.memoryUsage.external)}`, `` ].join("\n")); sections.push([ `Environment Variables (filtered):`, ...Object.entries(info.env).map(([key, value]) => ` ${key}=${value}`), `` ].join("\n")); return sections.join("\n"); } /** * Find project root by looking for package.json */ async findProjectRoot(startPath) { return startPath; } /** * Find mlld config file */ async findConfigFile(projectPath) { const configFiles = [ "mlld.config.json", ".mlldrc", ".mlldrc.json" ]; for (const configFile of configFiles) { path.join(projectPath, configFile); } return null; } /** * Get mlld version */ async getMlldVersion() { try { return "1.0.0"; } catch { return "unknown"; } } /** * Get filtered environment variables */ getFilteredEnv() { const filtered = {}; const includePatterns = [ /^MLLD_/, /^NODE_/, /^npm_/, /^PATH$/, /^HOME$/, /^USER$/, /^SHELL$/, /^LANG$/, /^LC_/, /^TERM/ ]; for (const [key, value] of Object.entries(process.env)) { if (includePatterns.some((pattern) => pattern.test(key))) { filtered[key] = value || ""; } } return filtered; } /** * Format bytes as human-readable */ formatBytes(bytes) { const units = [ "B", "KB", "MB", "GB", "TB" ]; let size = bytes; let unitIndex = 0; while (size >= 1024 && unitIndex < units.length - 1) { size /= 1024; unitIndex++; } return `${size.toFixed(2)} ${units[unitIndex]}`; } /** * Format duration in seconds as human-readable */ formatDuration(seconds) { const days = Math.floor(seconds / 86400); const hours = Math.floor(seconds % 86400 / 3600); const minutes = Math.floor(seconds % 3600 / 60); const secs = Math.floor(seconds % 60); const parts = []; if (days > 0) parts.push(`${days}d`); if (hours > 0) parts.push(`${hours}h`); if (minutes > 0) parts.push(`${minutes}m`); if (secs > 0 || parts.length === 0) parts.push(`${secs}s`); return parts.join(" "); } /** * Get mocked time for testing */ getMockedTime() { if (process.env.MLLD_MOCK_TIME) { if (/^\d+$/.test(process.env.MLLD_MOCK_TIME)) { return new Date(parseInt(process.env.MLLD_MOCK_TIME) * 1e3); } return new Date(process.env.MLLD_MOCK_TIME); } return null; } /** * Get nested value from object using dot notation */ getNestedValue(obj, path2) { const parts = path2.split("."); let current = obj; for (const part of parts) { if (current && typeof current === "object" && part in current) { current = current[part]; } else { return void 0; } } return current; } }; __name(_DebugResolver, "DebugResolver"); var DebugResolver = _DebugResolver; // core/resolvers/builtin/InputResolver.ts var _InputResolver = class _InputResolver { constructor(stdinContent) { __publicField(this, "name", "input"); __publicField(this, "description", "Provides merged stdin and environment variable data"); __publicField(this, "type", "input"); __publicField(this, "capabilities", { io: { read: true, write: false, list: false }, contexts: { import: true, path: false, output: false }, supportedContentTypes: [ "data", "text" ], defaultContentType: "data", priority: 1, cache: { strategy: "memory", ttl: { duration: -1 } // Never expire during session } }); __publicField(this, "inputData", null); __publicField(this, "stdinContent"); this.stdinContent = stdinContent; } canResolve(ref) { const cleanRef = ref.replace(/^@/, ""); return cleanRef === "input" || cleanRef.startsWith("input/"); } async resolve(ref, config) { if (!this.inputData) { await this.initializeInputData(); } if (!config?.context || config.context === "variable") { return { content: JSON.stringify(this.inputData, null, 2), contentType: "data", metadata: { source: "input", timestamp: /* @__PURE__ */ new Date() } }; } if (config.context === "import") { const exports = {}; const imports = config.requestedImports || []; if (imports.length === 0) { const exportData = { ...this.inputData }; delete exportData._meta; return { content: JSON.stringify(exportData), contentType: "data", metadata: { source: "input", timestamp: /* @__PURE__ */ new Date() } }; } for (const fieldName of imports) { const value = this.getFieldValue(fieldName); if (value !== null) { exports[fieldName] = value; } } return { content: JSON.stringify(exports), contentType: "data", metadata: { source: "input", timestamp: /* @__PURE__ */ new Date() } }; } throw new ResolverError("input resolver only supports variable and import contexts", ResolverErrorCode.UNSUPPORTED_CONTEXT, { resolverName: this.name, context: config?.context, operation: "resolve" }); } /** * Initialize input data from stdin and environment */ async initializeInputData() { const stdin = await this.readStdin(); const envVars = this.getEnvironmentVariables(); this.inputData = { ...envVars, ...stdin }; if (stdin.config || stdin.data) { this.inputData.config = stdin.config; this.inputData.data = stdin.data; } this.inputData._meta = { source: "INPUT", timestamp: (/* @__PURE__ */ new Date()).toISOString(), hasStdin: Object.keys(stdin).length > 0, envVarCount: Object.keys(envVars).length }; } /** * Read and parse stdin content */ async readStdin() { try { const content = this.stdinContent || ""; if (!content) { return {}; } try { const parsed = JSON.parse(content); return typeof parsed === "object" && parsed !== null ? parsed : { value: parsed }; } catch { return { stdin: content.trim() }; } } catch (error) { return {}; } } /** * Get filtered environment variables */ getEnvironmentVariables() { const filtered = {}; for (const [key, value] of Object.entries(process.env)) { if (key.startsWith("MLLD_") && value !== void 0) { filtered[key] = value; } } const includeVars = [ "NODE_ENV", "DEBUG", "CI", "HOME", "USER", "PATH" ]; for (const varName of includeVars) { if (process.env[varName] !== void 0) { filtered[varName] = process.env[varName]; } } return filtered; } /** * Get field value from input data */ getFieldValue(field) { if (!this.inputData) { return null; } switch (field.toLowerCase()) { case "content": return this.inputData.stdin || ""; case "json": return this.inputData; case "text": return this.inputData.stdin || ""; case "env": const env = {}; for (const [key, value] of Object.entries(this.inputData)) { if (typeof value === "string" && key !== "stdin" && key !== "_meta") { env[key] = value; } } return env; case "stdin": const stdinData = { ...this.inputData }; delete stdinData._meta; for (const key of Object.keys(stdinData)) { if (typeof stdinData[key] === "string" && key !== "stdin") { delete stdinData[key]; } } return stdinData; } const parts = field.split("."); let current = this.inputData; for (const part of parts) { if (current && typeof current === "object" && part in current) { current = current[part]; } else { return null; } } return current; } /** * Update stdin content (for testing or dynamic updates) */ setStdinContent(content) { this.stdinContent = content; this.inputData = null; } }; __name(_InputResolver, "InputResolver"); var InputResolver = _InputResolver; export { DebugResolver, InputResolver, NowResolver }; //# sourceMappingURL=builtin-PUSUPKEM.mjs.map //# sourceMappingURL=builtin-PUSUPKEM.mjs.map