UNPKG

@meldscience/meld

Version:

pipeable one-shot prompt scripting toolkit

108 lines 4.11 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.PromptScript = void 0; const fs_1 = require("fs"); const child_process_1 = require("child_process"); const errors_1 = require("./errors"); class PromptScript { constructor(options) { this.options = options; } /** * Main entry point. Orchestrates reading file, extracting commands, * executing them, and replacing placeholders. */ async process() { if (!(0, fs_1.existsSync)(this.options.inputFile)) { throw new errors_1.ToolError(`PromptScript: Input file does not exist: ${this.options.inputFile}`, 'FILE_NOT_FOUND'); } const rawContent = (0, fs_1.readFileSync)(this.options.inputFile, 'utf-8'); const commands = await this.extractCommands(rawContent); // If dry-run, skip actual execution let commandResults = []; if (!this.options.dryRun) { for (const cmd of commands) { const result = await this.executeCommand(cmd); commandResults.push(result); } } else { commandResults = commands.map((c) => ({ command: c, output: `# [DRY-RUN] Would have executed: ${c.command}` })); } const replacedContent = await this.replaceCommands(rawContent, commandResults); // Write to output file if specified if (this.options.outputFile) { (0, fs_1.writeFileSync)(this.options.outputFile, replacedContent); } return replacedContent; } /** * Scans markdown content for lines containing @cmd[...] * @param content entire markdown file text * @returns array of Command objects */ async extractCommands(content) { const cmdRegex = /@cmd\[(?<command>[^\]]+)\]/g; const lines = content.split('\n'); const commands = []; for (let i = 0; i < lines.length; i++) { const line = lines[i]; let match; while ((match = cmdRegex.exec(line)) !== null) { const commandStr = match.groups?.command || ''; commands.push({ raw: match[0], command: commandStr.trim(), lineNumber: i + 1 }); } } return commands; } /** * Executes a single shell command synchronously. * @param cmd object containing the command string * @returns command result with output */ async executeCommand(cmd) { try { const output = (0, child_process_1.execSync)(cmd.command, { encoding: 'utf-8' }); return { command: cmd, output }; } catch (error) { // Capture error but keep going return { command: cmd, output: '', error }; } } /** * Replaces each @cmd[...] in the original content with its execution result. * If there's an error, it inserts the error message into a fenced code block. * @param content original markdown * @param results command results * @returns final processed markdown */ async replaceCommands(content, results) { let finalContent = content; for (const result of results) { const placeholder = result.command.raw; let replacement; if (result.error) { const errMsg = `Command failed: ${result.command.command}\nError: ${result.error.message}`; replacement = `\`\`\`\n${errMsg}\n\`\`\``; } else { // If the output is code-like, we can fence it automatically, // but we'll keep it simple here: replacement = `\`\`\`\n${result.output.trim()}\n\`\`\``; } // Replace all occurrences of the placeholder finalContent = finalContent.replace(placeholder, replacement); } return finalContent; } } exports.PromptScript = PromptScript; //# sourceMappingURL=prompt-script.js.map