mlld
Version:
mlld: llm scripting language
1,294 lines (1,290 loc) • 66.5 kB
JavaScript
import { normalizeTransformerResult } from './chunk-UZUAAX2J.mjs';
import { init_CommandUtils, CommandUtils, prepareValueForShadow } from './chunk-XVCWUTXF.mjs';
import { coerceValueForStdin, interpolate, extractSection } from './chunk-6SG7EQJL.mjs';
import { wrapExecResult, wrapPipelineResult } from './chunk-GRNEVFPC.mjs';
import { DefaultDependencyChecker, checkDependencies } from './chunk-HPGSPG52.mjs';
import { AutoUnwrapManager } from './chunk-CEX4MM2H.mjs';
import { asText, isStructuredValue, looksLikeJsonString, wrapStructured } from './chunk-CQPPOI5P.mjs';
import { logger } from './chunk-PLP7R2Q4.mjs';
import { MlldInterpreterError, MlldCommandExecutionError } from './chunk-YVSXROKS.mjs';
import { isTemplateExecutable, isPipelineExecutable, isCommandExecutable, isCodeExecutable, isCommandRefExecutable, isSectionExecutable, isResolverExecutable } from './chunk-SON743RN.mjs';
import { isExecutableVariable } from './chunk-VKEM6RSR.mjs';
import { createStructuredValueVariable, createObjectVariable, createArrayVariable, createPrimitiveVariable, createSimpleTextVariable } from './chunk-CHF7KR7X.mjs';
import { isLoadContentResultArray, isLoadContentResult } from './chunk-MNK7EBJ3.mjs';
import { __name } from './chunk-NJQWMXLH.mjs';
// interpreter/eval/with-clause.ts
async function applyWithClause(input, withClause, env) {
let result = wrapExecResult(input);
if (withClause.pipeline && withClause.pipeline.length > 0) {
const { processPipeline } = await import('./unified-processor-SHTG77PF.mjs');
const pipelineResult = await processPipeline({
value: result,
env,
pipeline: withClause.pipeline,
format: withClause.format,
isRetryable: false
// with-clause doesn't track source function
});
result = wrapPipelineResult(pipelineResult);
}
if (withClause.needs) {
await checkDependencies2(withClause.needs, env);
}
return {
value: result,
env,
stdout: asText(result),
stderr: "",
exitCode: 0
};
}
__name(applyWithClause, "applyWithClause");
async function checkDependencies2(needs, env) {
if (needs.file) {
const exists = await env.fileSystem.exists(needs.file);
if (!exists) {
throw new MlldInterpreterError(`Required file not found: ${needs.file}`);
}
}
}
__name(checkDependencies2, "checkDependencies");
// interpreter/eval/exec-invocation.ts
init_CommandUtils();
// core/types/structured-value/StructuredValue.ts
var JSON_PRIMITIVES = /* @__PURE__ */ new Set(["true", "false", "null"]);
var _StructuredValue = class _StructuredValue {
constructor(raw, options = {}) {
this.jsonEvaluated = false;
this.raw = raw;
const detection = detectStructuredValue(raw, options);
this.format = detection.format;
this.jsonKind = detection.jsonKind;
this.recognizedReason = detection.reason;
this.origin = options.origin;
if (process.env.MLLD_DEBUG === "true" && detection.shouldWrap) {
const originSummary = options.origin ? `${options.origin.source}${options.origin.identifier ? `:${options.origin.identifier}` : ""}` : "unknown";
const preview = raw.length > 160 ? `${raw.slice(0, 160)}\u2026` : raw;
console.debug("[StructuredValue] recognized candidate", {
origin: originSummary,
format: detection.format,
reason: detection.reason,
kind: detection.jsonKind,
preview
});
}
}
static create(raw, options = {}) {
return new _StructuredValue(raw, options);
}
static detect(raw, options = {}) {
const detection = detectStructuredValue(raw, options);
return detection.shouldWrap ? new _StructuredValue(raw, options) : void 0;
}
static isStructuredValue(value) {
return value instanceof _StructuredValue;
}
toString() {
return this.raw;
}
valueOf() {
return this.raw;
}
[Symbol.toPrimitive]() {
return this.raw;
}
toJSON() {
return this.raw;
}
get text() {
return this.raw;
}
get data() {
if (this.format === "json") {
return this.asJson();
}
return this.raw;
}
hasJsonCandidate() {
return this.format === "json" || Boolean(this.jsonKind);
}
asJson() {
const result = this.tryParseJson();
if (!result.ok) {
throw result.error;
}
return result.value;
}
tryJson() {
return this.tryParseJson();
}
isJsonArray() {
const result = this.tryParseJson();
return result.ok && Array.isArray(result.value);
}
isJsonObject() {
const result = this.tryParseJson();
return result.ok && typeof result.value === "object" && result.value !== null && !Array.isArray(result.value);
}
asArray() {
const value = this.asJson();
if (!Array.isArray(value)) {
throw new Error("StructuredValue contains JSON that is not an array");
}
return value;
}
entries() {
const value = this.asJson();
if (!value || typeof value !== "object" || Array.isArray(value)) {
throw new Error("StructuredValue contains JSON that is not an object");
}
return Object.entries(value);
}
getJsonParseError() {
return this.jsonError;
}
tryParseJson() {
if (!this.hasJsonCandidate()) {
return { ok: false, error: new Error("StructuredValue is not recognized as JSON") };
}
if (!this.jsonEvaluated) {
this.jsonEvaluated = true;
try {
const trimmed = this.raw.trim();
this.jsonValue = JSON.parse(trimmed);
this.jsonError = void 0;
} catch (error) {
const err = error instanceof Error ? error : new Error(String(error));
this.jsonError = err;
if (process.env.MLLD_DEBUG === "true") {
const originSummary = this.origin ? `${this.origin.source}${this.origin.identifier ? `:${this.origin.identifier}` : ""}` : "unknown";
console.debug("[StructuredValue] JSON parse failed", {
origin: originSummary,
message: err.message
});
}
return { ok: false, error: err };
}
}
if (this.jsonError) {
return { ok: false, error: this.jsonError };
}
return { ok: true, value: this.jsonValue };
}
};
__name(_StructuredValue, "StructuredValue");
var StructuredValue = _StructuredValue;
function detectStructuredValue(raw, options = {}) {
const formatHint = normalizeFormatHint(options.formatHint);
const trimmed = raw.trim();
const allowPrimaries = options.allowPrimaries ?? formatHint === "json";
if (!trimmed) {
return {
shouldWrap: false,
format: formatHint ?? "text"
};
}
if (formatHint === "json") {
return {
shouldWrap: true,
format: "json",
jsonKind: classifyStructure(trimmed) ?? classifyPrimitive(trimmed, allowPrimaries),
reason: "hint"
};
}
const structuralKind = classifyStructure(trimmed);
if (structuralKind) {
return {
shouldWrap: true,
format: "json",
jsonKind: structuralKind,
reason: "structure"
};
}
const primitiveKind = classifyPrimitive(trimmed, allowPrimaries);
if (primitiveKind) {
return {
shouldWrap: true,
format: "json",
jsonKind: primitiveKind,
reason: "primitive"
};
}
return {
shouldWrap: false,
format: formatHint ?? "text"
};
}
__name(detectStructuredValue, "detectStructuredValue");
function normalizeFormatHint(formatHint) {
if (!formatHint) return void 0;
switch (formatHint) {
case "json":
case "csv":
case "xml":
case "text":
return formatHint;
default:
return "unknown";
}
}
__name(normalizeFormatHint, "normalizeFormatHint");
function classifyStructure(trimmed) {
if (!trimmed) return void 0;
const first = trimmed[0];
const last = trimmed[trimmed.length - 1];
if (first === "{" && last === "}") {
return "object";
}
if (first === "[" && last === "]") {
return "array";
}
return void 0;
}
__name(classifyStructure, "classifyStructure");
function classifyPrimitive(trimmed, allowPrimaries = true) {
if (!allowPrimaries) return void 0;
if (JSON_PRIMITIVES.has(trimmed)) {
return "primitive";
}
if (/^-?\d+$/.test(trimmed)) {
const asNumber = Number(trimmed);
if (Number.isSafeInteger(asNumber)) {
return "primitive";
}
return void 0;
}
if (/^-?(?:0|[1-9]\d*)(?:\.\d+)?(?:[eE][+-]?\d+)?$/.test(trimmed)) {
return "primitive";
}
if (trimmed.startsWith('"') && trimmed.endsWith('"')) {
return "primitive";
}
return void 0;
}
__name(classifyPrimitive, "classifyPrimitive");
// interpreter/eval/exec-invocation.ts
async function resolveStdinInput(stdinSource, env) {
if (stdinSource === null || stdinSource === void 0) {
return "";
}
const { evaluate } = await import('./interpreter-SBNF6N66.mjs');
const result = await evaluate(stdinSource, env, { isExpression: true });
let value = result.value;
const { isVariable, resolveValue, ResolutionContext } = await import('./variable-resolution-QKOWHUJ3.mjs');
if (isVariable(value)) {
value = await resolveValue(value, env, ResolutionContext.CommandExecution);
}
return coerceValueForStdin(value);
}
__name(resolveStdinInput, "resolveStdinInput");
var _SimpleMetadataShelf = class _SimpleMetadataShelf {
constructor() {
this.shelf = /* @__PURE__ */ new Map();
}
storeMetadata(value) {
if (isLoadContentResultArray(value)) {
for (const item of value) {
if (isLoadContentResult(item)) {
this.shelf.set(item.content, item);
}
}
} else if (isLoadContentResult(value)) {
this.shelf.set(value.content, value);
}
}
restoreMetadata(value) {
if (!Array.isArray(value)) return value;
const restored = [];
let hasRestorable = false;
for (const item of value) {
if (typeof item === "string" && this.shelf.has(item)) {
restored.push(this.shelf.get(item));
hasRestorable = true;
} else {
restored.push(item);
}
}
return hasRestorable ? restored : value;
}
clear() {
this.shelf.clear();
}
};
__name(_SimpleMetadataShelf, "SimpleMetadataShelf");
var SimpleMetadataShelf = _SimpleMetadataShelf;
var metadataShelf = new SimpleMetadataShelf();
async function evaluateExecInvocation(node, env) {
const createEvalResult = /* @__PURE__ */ __name((value, targetEnv, options) => {
const wrapped = wrapExecResult(value, options);
return {
value: wrapped,
env: targetEnv,
stdout: asText(wrapped),
stderr: "",
exitCode: 0
};
}, "createEvalResult");
const toPipelineInput = /* @__PURE__ */ __name((value, options) => {
return wrapExecResult(value, options);
}, "toPipelineInput");
if (process.env.MLLD_DEBUG === "true") {
console.error("[evaluateExecInvocation] Entry:", {
hasCommandRef: !!node.commandRef,
hasWithClause: !!node.withClause,
hasPipeline: !!node.withClause?.pipeline,
pipelineLength: node.withClause?.pipeline?.length
});
}
if (process.env.DEBUG_WHEN || process.env.DEBUG_EXEC) {
logger.debug("evaluateExecInvocation called with:", { commandRef: node.commandRef });
}
let commandName;
let args = [];
if (!node.commandRef && node.name) {
commandName = node.name;
args = node.arguments || [];
} else if (node.commandRef) {
if (node.commandRef.name) {
commandName = node.commandRef.name;
args = node.commandRef.args || [];
} else if (typeof node.commandRef.identifier === "string") {
commandName = node.commandRef.identifier;
args = node.commandRef.args || [];
} else if (Array.isArray(node.commandRef.identifier) && node.commandRef.identifier.length > 0) {
const identifierNode = node.commandRef.identifier[0];
if (identifierNode.type === "VariableReference" && identifierNode.identifier) {
commandName = identifierNode.identifier;
} else if (identifierNode.type === "Text" && identifierNode.content) {
commandName = identifierNode.content;
} else {
throw new Error("Unable to extract command name from identifier array");
}
args = node.commandRef.args || [];
} else {
throw new Error("CommandReference missing both name and identifier");
}
} else {
throw new Error("ExecInvocation node missing both commandRef and name");
}
if (!commandName) {
throw new MlldInterpreterError("ExecInvocation has no command identifier");
}
let variable;
const commandRefWithObject = node.commandRef;
if (node.commandRef && (commandRefWithObject.objectReference || commandRefWithObject.objectSource)) {
const builtinMethods = ["includes", "length", "indexOf", "join", "split", "toLowerCase", "toUpperCase", "trim", "startsWith", "endsWith"];
if (builtinMethods.includes(commandName)) {
let objectValue2;
if (commandRefWithObject.objectReference) {
const objectRef2 = commandRefWithObject.objectReference;
const objectVar2 = env.getVariable(objectRef2.identifier);
if (!objectVar2) {
throw new MlldInterpreterError(`Object not found: ${objectRef2.identifier}`);
}
const { extractVariableValue: extractVariableValue2 } = await import('./variable-resolution-QKOWHUJ3.mjs');
objectValue2 = await extractVariableValue2(objectVar2, env);
if (objectRef2.fields && objectRef2.fields.length > 0) {
for (const field of objectRef2.fields) {
if (typeof objectValue2 === "object" && objectValue2 !== null) {
objectValue2 = objectValue2[field.value];
} else {
throw new MlldInterpreterError(`Cannot access field ${field.value} on non-object`);
}
}
}
} else if (commandRefWithObject.objectSource) {
const srcResult = await evaluateExecInvocation(commandRefWithObject.objectSource, env);
if (srcResult && typeof srcResult === "object") {
if (srcResult.value !== void 0) {
const { resolveValue, ResolutionContext } = await import('./variable-resolution-QKOWHUJ3.mjs');
objectValue2 = await resolveValue(srcResult.value, env, ResolutionContext.Display);
} else if (typeof srcResult.stdout === "string") {
objectValue2 = srcResult.stdout;
}
}
}
if (typeof objectValue2 === "undefined") {
throw new MlldInterpreterError("Unable to resolve object value for builtin method invocation");
}
if (isStructuredValue(objectValue2)) {
objectValue2 = objectValue2.type === "array" ? objectValue2.data : asText(objectValue2);
} else if (StructuredValue.isStructuredValue?.(objectValue2)) {
objectValue2 = objectValue2.text;
}
const evaluatedArgs2 = [];
for (const arg of args) {
const { evaluateDataValue } = await import('./data-value-evaluator-NMZLI3DJ.mjs');
const evaluatedArg = await evaluateDataValue(arg, env);
evaluatedArgs2.push(evaluatedArg);
}
let result2;
switch (commandName) {
case "includes":
if (Array.isArray(objectValue2) || typeof objectValue2 === "string") {
result2 = objectValue2.includes(evaluatedArgs2[0]);
} else {
throw new MlldInterpreterError(`Cannot call .includes() on ${typeof objectValue2}`);
}
break;
case "length":
if (Array.isArray(objectValue2) || typeof objectValue2 === "string") {
result2 = objectValue2.length;
} else {
throw new MlldInterpreterError(`Cannot call .length() on ${typeof objectValue2}`);
}
break;
case "indexOf":
if (Array.isArray(objectValue2) || typeof objectValue2 === "string") {
result2 = objectValue2.indexOf(evaluatedArgs2[0]);
} else {
throw new MlldInterpreterError(`Cannot call .indexOf() on ${typeof objectValue2}`);
}
break;
case "join":
if (Array.isArray(objectValue2)) {
result2 = objectValue2.join(evaluatedArgs2[0] || ",");
} else {
throw new MlldInterpreterError(`Cannot call .join() on ${typeof objectValue2}`);
}
break;
case "split":
if (typeof objectValue2 === "string") {
result2 = objectValue2.split(evaluatedArgs2[0] || "");
} else {
throw new MlldInterpreterError(`Cannot call .split() on ${typeof objectValue2}`);
}
break;
case "toLowerCase":
if (typeof objectValue2 === "string") {
result2 = objectValue2.toLowerCase();
} else {
throw new MlldInterpreterError(`Cannot call .toLowerCase() on ${typeof objectValue2}`);
}
break;
case "toUpperCase":
if (typeof objectValue2 === "string") {
result2 = objectValue2.toUpperCase();
} else {
throw new MlldInterpreterError(`Cannot call .toUpperCase() on ${typeof objectValue2}`);
}
break;
case "trim":
if (typeof objectValue2 === "string") {
result2 = objectValue2.trim();
} else {
throw new MlldInterpreterError(`Cannot call .trim() on ${typeof objectValue2}`);
}
break;
case "startsWith":
if (typeof objectValue2 === "string") {
result2 = objectValue2.startsWith(evaluatedArgs2[0]);
} else {
throw new MlldInterpreterError(`Cannot call .startsWith() on ${typeof objectValue2}`);
}
break;
case "endsWith":
if (typeof objectValue2 === "string") {
result2 = objectValue2.endsWith(evaluatedArgs2[0]);
} else {
throw new MlldInterpreterError(`Cannot call .endsWith() on ${typeof objectValue2}`);
}
break;
default:
throw new MlldInterpreterError(`Unknown builtin method: ${commandName}`);
}
const postFieldsBuiltin = node.fields || [];
if (postFieldsBuiltin && postFieldsBuiltin.length > 0) {
const { accessField } = await import('./field-access-YANGDGQP.mjs');
for (const f of postFieldsBuiltin) {
result2 = await accessField(result2, f, { env, sourceLocation: node.location });
}
}
const normalized = normalizeTransformerResult(commandName, result2);
const resolvedValue = normalized.value;
const wrapOptions = normalized.options;
if (node.withClause) {
if (node.withClause.pipeline) {
const { processPipeline } = await import('./unified-processor-SHTG77PF.mjs');
const pipelineInputValue = toPipelineInput(resolvedValue, wrapOptions);
const pipelineResult = await processPipeline({
value: pipelineInputValue,
env,
node,
identifier: node.identifier
});
return applyWithClause(pipelineResult, { ...node.withClause, pipeline: void 0 }, env);
} else {
return applyWithClause(resolvedValue, node.withClause, env);
}
}
return createEvalResult(resolvedValue, env, wrapOptions);
}
if (commandRefWithObject.objectSource && !commandRefWithObject.objectReference) {
throw new MlldInterpreterError(`Only builtin methods are supported on exec results (got: ${commandName})`);
}
const objectRef = commandRefWithObject.objectReference;
const objectVar = env.getVariable(objectRef.identifier);
if (!objectVar) {
throw new MlldInterpreterError(`Object not found: ${objectRef.identifier}`);
}
const { extractVariableValue } = await import('./variable-resolution-QKOWHUJ3.mjs');
const objectValue = await extractVariableValue(objectVar, env);
if (objectRef.fields && objectRef.fields.length > 0) {
let currentValue = objectValue;
for (const field of objectRef.fields) {
if (process.env.DEBUG_EXEC) {
logger.debug("Accessing field", {
fieldType: field.type,
fieldValue: field.value,
currentValueType: typeof currentValue,
currentValueKeys: typeof currentValue === "object" && currentValue !== null ? Object.keys(currentValue) : "not-object"
});
}
if (typeof currentValue === "object" && currentValue !== null) {
currentValue = currentValue[field.value];
if (process.env.DEBUG_EXEC) {
logger.debug("Field access result", {
fieldValue: field.value,
resultType: typeof currentValue,
resultKeys: typeof currentValue === "object" && currentValue !== null ? Object.keys(currentValue) : "not-object"
});
}
} else {
throw new MlldInterpreterError(`Cannot access field ${field.value} on non-object`);
}
}
if (typeof currentValue === "object" && currentValue !== null) {
const fieldValue = currentValue[commandName];
variable = fieldValue;
}
} else {
if (typeof objectValue === "object" && objectValue !== null) {
let fieldValue;
if (objectValue.type === "object" && objectValue.properties) {
fieldValue = objectValue.properties[commandName];
} else {
fieldValue = objectValue[commandName];
}
variable = fieldValue;
}
}
if (!variable) {
throw new MlldInterpreterError(`Method not found: ${commandName} on ${objectRef.identifier}`);
}
if (typeof variable === "object" && variable !== null && "__executable" in variable && variable.__executable) {
let metadata = variable.metadata || {};
if (metadata.capturedShadowEnvs && typeof metadata.capturedShadowEnvs === "object") {
const needsDeserialization = Object.entries(metadata.capturedShadowEnvs).some(
([lang, env2]) => env2 && !(env2 instanceof Map)
);
if (needsDeserialization) {
metadata = {
...metadata,
capturedShadowEnvs: deserializeShadowEnvs(metadata.capturedShadowEnvs)
};
}
}
if (metadata.capturedModuleEnv && !(metadata.capturedModuleEnv instanceof Map)) {
const { VariableImporter } = await import('./VariableImporter-KZM575JG.mjs');
const importer = new VariableImporter(null);
const moduleEnvMap = importer.deserializeModuleEnv(metadata.capturedModuleEnv);
for (const [_, variable2] of moduleEnvMap) {
if (variable2.type === "executable" && variable2.metadata) {
variable2.metadata.capturedModuleEnv = moduleEnvMap;
}
}
metadata = {
...metadata,
capturedModuleEnv: moduleEnvMap
};
}
const { createExecutableVariable } = await import('./VariableFactories-P3MMD767.mjs');
variable = createExecutableVariable(
commandName,
"command",
// Default type - the real type is in executableDef
"",
// Empty template - the real template is in executableDef
variable.paramNames || [],
void 0,
// No language here - it's in executableDef
{
directive: "exe",
syntax: "braces",
hasInterpolation: false,
isMultiLine: false
},
{
executableDef: variable.executableDef,
...metadata
}
);
}
} else {
variable = env.getVariable(commandName);
if (!variable) {
throw new MlldInterpreterError(`Command not found: ${commandName}`);
}
}
if (!isExecutableVariable(variable)) {
throw new MlldInterpreterError(`Variable ${commandName} is not executable (type: ${variable.type})`);
}
if (variable.metadata?.isBuiltinTransformer && variable.metadata?.transformerImplementation) {
if (commandName === "typeof" || commandName === "TYPEOF") {
if (args.length > 0) {
const arg = args[0];
if (arg && typeof arg === "object" && "type" in arg && arg.type === "VariableReference") {
const varRef = arg;
const varName = varRef.identifier;
const varObj = env.getVariable(varName);
if (varObj) {
let typeInfo = varObj.type;
if (varObj.type === "simple-text" && "subtype" in varObj) {
const subtype = varObj.subtype;
if (subtype && subtype !== "simple" && subtype !== "interpolated-text") {
typeInfo = subtype;
}
} else if (varObj.type === "primitive" && "primitiveType" in varObj) {
typeInfo = `primitive (${varObj.primitiveType})`;
} else if (varObj.type === "object") {
const objValue = varObj.value;
if (objValue && typeof objValue === "object") {
const keys = Object.keys(objValue);
typeInfo = `object (${keys.length} properties)`;
}
} else if (varObj.type === "array") {
const arrValue = varObj.value;
if (Array.isArray(arrValue)) {
typeInfo = `array (${arrValue.length} items)`;
}
} else if (varObj.type === "executable") {
const execDef = varObj.metadata?.executableDef;
if (execDef && "type" in execDef) {
typeInfo = `executable (${execDef.type})`;
}
}
if (varObj.source?.directive) {
typeInfo += ` [from /${varObj.source.directive}]`;
}
const result3 = await variable.metadata.transformerImplementation(`__MLLD_VARIABLE_OBJECT__:${typeInfo}`);
const normalized2 = normalizeTransformerResult(commandName, result3);
const resolvedValue2 = normalized2.value;
const wrapOptions2 = normalized2.options;
if (node.withClause) {
if (node.withClause.pipeline) {
const { processPipeline } = await import('./unified-processor-SHTG77PF.mjs');
const pipelineInputValue = toPipelineInput(resolvedValue2, wrapOptions2);
const pipelineResult = await processPipeline({
value: pipelineInputValue,
env,
node,
identifier: node.identifier
});
return applyWithClause(pipelineResult, { ...node.withClause, pipeline: void 0 }, env);
} else {
return applyWithClause(resolvedValue2, node.withClause, env);
}
}
return createEvalResult(resolvedValue2, env, wrapOptions2);
}
}
}
}
let inputValue = "";
if (args.length > 0) {
const arg = args[0];
if (typeof arg === "string") {
inputValue = arg;
} else if (arg && typeof arg === "object") {
inputValue = await interpolate([arg], env);
} else {
inputValue = String(arg);
}
}
const result2 = await variable.metadata.transformerImplementation(inputValue);
const normalized = normalizeTransformerResult(commandName, result2);
const resolvedValue = normalized.value;
const wrapOptions = normalized.options;
if (node.withClause) {
if (node.withClause.pipeline) {
const { processPipeline } = await import('./unified-processor-SHTG77PF.mjs');
const pipelineInputValue = toPipelineInput(resolvedValue, wrapOptions);
const pipelineResult = await processPipeline({
value: pipelineInputValue,
env,
node,
identifier: node.identifier
});
return applyWithClause(pipelineResult, { ...node.withClause, pipeline: void 0 }, env);
} else {
return applyWithClause(resolvedValue, node.withClause, env);
}
}
return createEvalResult(resolvedValue, env, wrapOptions);
}
const definition = variable.metadata?.executableDef;
if (!definition) {
throw new MlldInterpreterError(`Executable ${commandName} has no definition in metadata`);
}
let execEnv = env.createChild();
if (variable?.metadata?.capturedModuleEnv instanceof Map) {
execEnv.setCapturedModuleEnv(variable.metadata.capturedModuleEnv);
}
const params = definition.paramNames || [];
const evaluatedArgStrings = [];
const evaluatedArgs = [];
for (const arg of args) {
let argValue;
let argValueAny;
if (isStructuredValue(arg)) {
argValueAny = arg;
argValue = asText(arg);
} else if (typeof arg === "string" || typeof arg === "number" || typeof arg === "boolean") {
argValue = String(arg);
argValueAny = arg;
} else if (arg && typeof arg === "object" && "type" in arg) {
switch (arg.type) {
case "WhenExpression": {
const { evaluateWhenExpression } = await import('./when-expression-B2BMDHFN.mjs');
const whenRes = await evaluateWhenExpression(arg, env);
argValueAny = whenRes.value;
if (argValueAny === void 0) {
argValue = "undefined";
} else if (typeof argValueAny === "object") {
try {
argValue = JSON.stringify(argValueAny);
} catch {
argValue = String(argValueAny);
}
} else {
argValue = String(argValueAny);
}
break;
}
case "foreach":
case "foreach-command": {
const { evaluateForeachCommand } = await import('./foreach-DVSY36Z4.mjs');
const arr = await evaluateForeachCommand(arg, env);
argValueAny = arr;
argValue = JSON.stringify(arr);
break;
}
case "object":
const { evaluateDataValue } = await import('./data-value-evaluator-NMZLI3DJ.mjs');
argValueAny = await evaluateDataValue(arg, env);
argValue = JSON.stringify(argValueAny);
break;
case "array":
const { evaluateDataValue: evalArray } = await import('./data-value-evaluator-NMZLI3DJ.mjs');
argValueAny = await evalArray(arg, env);
argValue = JSON.stringify(argValueAny);
break;
case "VariableReference":
const varRef = arg;
const varName = varRef.identifier;
const variable2 = env.getVariable(varName);
if (variable2) {
let value = variable2.value;
const { isTemplate } = await import('./variable-KWBNZEAM.mjs');
if (isTemplate(variable2)) {
if (Array.isArray(value)) {
value = await interpolate(value, env);
} else if (variable2.metadata?.templateAst && Array.isArray(variable2.metadata.templateAst)) {
value = await interpolate(variable2.metadata.templateAst, env);
}
}
if (varRef.fields && varRef.fields.length > 0) {
const { accessFields } = await import('./field-access-YANGDGQP.mjs');
const accessed = await accessFields(value, varRef.fields, {
env,
preserveContext: false,
sourceLocation: varRef.location
});
value = accessed;
}
if (isStructuredValue(value)) {
argValueAny = value;
argValue = asText(value);
} else {
argValueAny = value;
if (value === void 0) {
argValue = "undefined";
} else if (typeof value === "object" && value !== null) {
try {
argValue = JSON.stringify(value);
} catch (e) {
argValue = String(value);
}
} else {
argValue = String(value);
}
}
} else {
argValue = await interpolate([arg], env, "default" /* Default */);
argValueAny = argValue;
}
break;
case "ExecInvocation": {
const nestedResult = await evaluateExecInvocation(arg, env);
if (nestedResult && nestedResult.value !== void 0) {
argValueAny = nestedResult.value;
} else if (nestedResult && nestedResult.stdout !== void 0) {
argValueAny = nestedResult.stdout;
} else {
argValueAny = void 0;
}
if (argValueAny === void 0) {
argValue = "undefined";
} else if (isStructuredValue(argValueAny)) {
argValue = asText(argValueAny);
} else if (typeof argValueAny === "object") {
try {
argValue = JSON.stringify(argValueAny);
} catch {
argValue = String(argValueAny);
}
} else {
argValue = String(argValueAny);
}
break;
}
case "Text":
argValue = await interpolate([arg], env, "default" /* Default */);
argValueAny = argValue;
break;
default:
argValue = await interpolate([arg], env, "default" /* Default */);
try {
argValueAny = JSON.parse(argValue);
} catch {
argValueAny = argValue;
}
break;
}
} else {
argValue = String(arg);
argValueAny = arg;
}
evaluatedArgStrings.push(argValue);
evaluatedArgs.push(argValueAny);
}
const originalVariables = [];
for (let i = 0; i < args.length; i++) {
const arg = args[i];
if (arg && typeof arg === "object" && "type" in arg && arg.type === "VariableReference") {
const varRef = arg;
const varName = varRef.identifier;
const variable2 = env.getVariable(varName);
if (variable2 && !varRef.fields) {
const { isTemplate } = await import('./variable-KWBNZEAM.mjs');
if (isTemplate(variable2) && typeof evaluatedArgs[i] === "string") {
originalVariables[i] = void 0;
} else {
originalVariables[i] = variable2;
}
if (process.env.MLLD_DEBUG === "true") {
const subtype = variable2.type === "primitive" && "primitiveType" in variable2 ? variable2.primitiveType : variable2.subtype;
logger.debug(`Preserving original Variable for arg ${i}:`, {
varName,
variableType: variable2.type,
variableSubtype: subtype,
isPrimitive: typeof variable2.value !== "object" || variable2.value === null
});
}
}
}
}
for (let i = 0; i < params.length; i++) {
const paramName = params[i];
const argValue = evaluatedArgs[i];
const argStringValue = evaluatedArgStrings[i];
if (argValue !== void 0) {
let paramVar;
const originalVar = originalVariables[i];
const isShellCode = definition.type === "code" && typeof definition.language === "string" && (definition.language === "bash" || definition.language === "sh");
const shouldReuseOriginal = originalVar && !isShellCode && definition.type !== "command";
if (shouldReuseOriginal) {
paramVar = {
...originalVar,
name: paramName,
metadata: {
...originalVar.metadata,
isSystem: true,
isParameter: true
}
};
if (process.env.MLLD_DEBUG === "true") {
const subtype = paramVar.type === "primitive" && "primitiveType" in paramVar ? paramVar.primitiveType : paramVar.subtype;
logger.debug(`Using original Variable for param ${paramName}:`, {
type: paramVar.type,
subtype,
hasMetadata: !!paramVar.metadata
});
}
} else {
const preservedValue = argValue !== void 0 ? argValue : argStringValue;
if (isStructuredValue(preservedValue)) {
paramVar = createStructuredValueVariable(
paramName,
preservedValue,
{
directive: "var",
syntax: "reference",
hasInterpolation: false,
isMultiLine: false
},
{
isSystem: true,
isParameter: true
}
);
} else if (preservedValue !== void 0 && preservedValue !== null && typeof preservedValue === "object" && !Array.isArray(preservedValue)) {
paramVar = createObjectVariable(
paramName,
preservedValue,
true,
{
directive: "var",
syntax: "object",
hasInterpolation: false,
isMultiLine: false
},
{
isSystem: true,
isParameter: true
}
);
} else if (Array.isArray(preservedValue)) {
paramVar = createArrayVariable(
paramName,
preservedValue,
true,
{
directive: "var",
syntax: "array",
hasInterpolation: false,
isMultiLine: false
},
{
isSystem: true,
isParameter: true
}
);
} else if (typeof preservedValue === "number" || typeof preservedValue === "boolean" || preservedValue === null) {
paramVar = createPrimitiveVariable(
paramName,
preservedValue,
{
directive: "var",
syntax: "literal",
hasInterpolation: false,
isMultiLine: false
},
{
isSystem: true,
isParameter: true
}
);
} else {
paramVar = createSimpleTextVariable(
paramName,
argStringValue,
{
directive: "var",
syntax: "quoted",
hasInterpolation: false,
isMultiLine: false
},
{
isSystem: true,
isParameter: true
}
);
}
}
execEnv.setParameterVariable(paramName, paramVar);
}
}
let result;
if (isTemplateExecutable(definition)) {
const templateResult = await interpolate(definition.template, execEnv);
if (isStructuredValue(templateResult)) {
result = templateResult;
} else if (typeof templateResult === "string") {
if (looksLikeJsonString(templateResult)) {
try {
const parsed = JSON.parse(templateResult.trim());
const typeHint = Array.isArray(parsed) ? "array" : "object";
result = wrapStructured(parsed, typeHint, templateResult);
} catch {
result = templateResult;
}
} else {
result = templateResult;
}
} else {
result = templateResult;
}
} else if (isPipelineExecutable(definition)) {
const { processPipeline } = await import('./unified-processor-SHTG77PF.mjs');
const pipelineResult = await processPipeline({
value: "",
env: execEnv,
pipeline: definition.pipeline,
format: definition.format,
identifier: commandName,
location: node.location,
isRetryable: false
});
result = typeof pipelineResult === "string" ? pipelineResult : String(pipelineResult ?? "");
} else if (isCommandExecutable(definition)) {
const referencedInTemplate = /* @__PURE__ */ new Set();
try {
const nodes = definition.commandTemplate;
if (Array.isArray(nodes)) {
for (const n of nodes) {
if (n && typeof n === "object" && n.type === "VariableReference" && typeof n.identifier === "string") {
referencedInTemplate.add(n.identifier);
} else if (n && typeof n === "object" && n.type === "Text" && typeof n.content === "string") {
for (const pname of params) {
const re = new RegExp(`@${pname}(?![A-Za-z0-9_])`);
if (re.test(n.content)) {
referencedInTemplate.add(pname);
}
}
}
}
}
} catch {
}
let command = await interpolate(definition.commandTemplate, execEnv, "shell-command" /* ShellCommand */);
command = command.replace(/\\n/g, "\n").replace(/\\t/g, " ").replace(/\\r/g, "\r").replace(/\\0/g, "\0");
if (process.env.DEBUG_WHEN || process.env.DEBUG_EXEC) {
logger.debug("Executing command", {
command,
commandTemplate: definition.commandTemplate
});
}
const envVars = {};
const escapeRegex = /* @__PURE__ */ __name((s) => s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"), "escapeRegex");
const paramRegexCache = {};
const referencesParam = /* @__PURE__ */ __name((cmd, name) => {
if (referencedInTemplate.has(name)) return true;
if (!paramRegexCache[name]) {
const n = escapeRegex(name);
paramRegexCache[name] = {
simple: new RegExp(`(^|[^\\\\])\\$${n}(?![A-Za-z0-9_])`),
braced: new RegExp(`\\$\\{${n}\\}`)
};
}
const { simple, braced } = paramRegexCache[name];
return simple.test(cmd) || braced.test(cmd);
}, "referencesParam");
for (let i = 0; i < params.length; i++) {
const paramName = params[i];
if (!referencesParam(command, paramName)) continue;
const paramVar = execEnv.getVariable(paramName);
if (paramVar && typeof paramVar.value === "object" && paramVar.value !== null) {
try {
envVars[paramName] = JSON.stringify(paramVar.value);
} catch {
envVars[paramName] = evaluatedArgStrings[i];
}
} else {
envVars[paramName] = evaluatedArgStrings[i];
}
}
const perVarMax = (() => {
const v = process.env.MLLD_MAX_SHELL_ENV_VAR_SIZE;
if (!v) return 128 * 1024;
const n = Number(v);
return Number.isFinite(n) && n > 0 ? Math.floor(n) : 128 * 1024;
})();
const needsBashFallback = Object.values(envVars).some((v) => Buffer.byteLength(v || "", "utf8") > perVarMax);
const fallbackDisabled = (() => {
const v = (process.env.MLLD_DISABLE_COMMAND_BASH_FALLBACK || "").toLowerCase();
return v === "1" || v === "true" || v === "yes" || v === "on";
})();
if (needsBashFallback && !fallbackDisabled) {
let fallbackCommand = "";
try {
const nodes = definition.commandTemplate;
if (Array.isArray(nodes)) {
for (const n of nodes) {
if (n && typeof n === "object" && n.type === "VariableReference" && typeof n.identifier === "string" && params.includes(n.identifier)) {
fallbackCommand += `"$${n.identifier}"`;
} else if (n && typeof n === "object" && "content" in n) {
fallbackCommand += String(n.content || "");
} else if (typeof n === "string") {
fallbackCommand += n;
} else {
fallbackCommand += await interpolate([n], execEnv, "shell-command" /* ShellCommand */);
}
}
} else {
fallbackCommand = command;
}
} catch {
fallbackCommand = command;
}
try {
CommandUtils.validateAndParseCommand(fallbackCommand);
} catch (error) {
throw new MlldCommandExecutionError(
error instanceof Error ? error.message : String(error),
context?.sourceLocation,
{
command: fallbackCommand,
exitCode: 1,
duration: 0,
stderr: error instanceof Error ? error.message : String(error),
workingDirectory: execEnv.getProjectRoot?.() || "",
directiveType: context?.directiveType || "run"
}
);
}
const codeParams = {};
for (let i = 0; i < params.length; i++) {
const paramName = params[i];
if (!referencesParam(command, paramName)) continue;
codeParams[paramName] = evaluatedArgs[i];
}
if (process.env.MLLD_DEBUG === "true") {
console.error("[exec-invocation] Falling back to bash heredoc for oversized command params", {
fallbackSnippet: fallbackCommand.slice(0, 120),
paramCount: Object.keys(codeParams).length
});
}
const commandOutput = await execEnv.executeCode(fallbackCommand, "sh", codeParams);
if (typeof commandOutput === "string" && commandOutput.trim()) {
const trimmed = commandOutput.trim();
if (trimmed.startsWith("{") && trimmed.endsWith("}") || trimmed.startsWith("[") && trimmed.endsWith("]")) {
try {
result = JSON.parse(trimmed);
} catch {
result = commandOutput;
}
} else {
result = commandOutput;
}
} else {
result = commandOutput;
}
} else {
let stdinInput;
if (definition.withClause && "stdin" in definition.withClause) {
stdinInput = await resolveStdinInput(definition.withClause.stdin, execEnv);
}
const commandOptions = stdinInput !== void 0 ? { env: envVars, input: stdinInput } : { env: envVars };
const commandOutput = await execEnv.executeCommand(command, commandOptions);
if (typeof commandOutput === "string" && commandOutput.trim()) {
const trimmed = commandOutput.trim();
if (trimmed.startsWith("{") && trimmed.endsWith("}") || trimmed.startsWith("[") && trimmed.endsWith("]")) {
try {
result = JSON.parse(trimmed);
} catch {
result = commandOutput;
}
} else {
result = commandOutput;
}
} else {
result = commandOutput;
}
}
if (definition.withClause) {
if (definition.withClause.needs) {
const checker = new DefaultDependencyChecker();
await checkDependencies(definition.withClause.needs, checker, variable.metadata?.definedAt || node.location);
}
if (definition.withClause.pipeline && definition.withClause.pipeline.length > 0) {
const { processPipeline } = await import('./unified-processor-SHTG77PF.mjs');
const pipelineInput = typeof result === "string" ? result : result === void 0 || result === null ? "" : JSON.stringify(result);
const pipelineResult = await processPipeline({
value: pipelineInput,
env: execEnv,
pipeline: definition.withClause.pipeline,
format: definition.withClause.format,
isRetryable: false,
identifier: commandName,
location: variable.metadata?.definedAt || node.location
});
if (typeof pipelineResult === "string") {
const trimmed = pipelineResult.trim();
if (trimmed) {
try {
result = JSON.parse(trimmed);
} catch {
result = pipelineResult;
}
} else {
result = pipelineResult;
}
} else {
result = pipelineResult;
}
}
}
} else if (isCodeExecutable(definition)) {
if (definition.language === "mlld-when") {
const whenExprNode = definition.codeTemplate[0];
if (!whenExprNode || whenExprNode.type !== "WhenExpression") {
throw new MlldInterpreterError("mlld-when executable missing WhenExpression node");
}
const { evaluateWhenExpression } = await import('./when-expression-B2BMDHFN.mjs');
const whenResult = await evaluateWhenExpression(whenExprNode, execEnv);
let value = whenResult.value;
if (value && typeof value === "object" && value.__whenEffect === "show") {
value = value.text ?? "";
} else if (isStructuredValue(value) && value.data && typeof value.data === "object" && value.data.__whenEffect === "show") {
value = value.data.text ?? asText(value);
}
result = value;
execEnv = whenResult.env;
} else if (definition.language === "mlld-foreach") {
const foreachNode = definition.codeTemplate[0];
const { evaluateForeachCommand } = await import('./foreach-DVSY36Z4.mjs');
result = await evaluateForeachCommand(foreachNode, execEnv);
} else if (definition.language === "mlld-for") {
const forExprNode = definition.codeTemplate[0];
if (!forExprNode || forExprNode.type !== "ForExpression") {
throw new MlldInterpreterError("mlld-for executable missing ForExpression node");
}
const { evaluateForExpression } = await import('./for-TEFC6TVV.mjs');
result = await evaluateForExpression(forExprNode, execEnv);
} else {
let code;
if (definition.language === "bash" || definition.language === "sh") {
if (Array.isArray(definition.codeTemplate)) {
code = definition.codeTemplate.map((node2) => {
if (typeof node2 === "string") return node2;
if (node2 && typeof node2 === "object" && "content" in node2) return node2.content || "";
return "";
}).join("");
} else if (typeof definition.codeTemplate === "string") {
code = definition.codeTemplate;
} else {
code = "";
}
} else {
code = await interpolate(definition.codeTemplate, execEnv);
}
const { ASTEvaluator } = await import('./ast-evaluator-PJNDX3OD.mjs');
const codeParams = {};
const variableMetadata = {};
for (let i = 0; i < params.length; i++) {
const paramName = params[i];
const paramVar = execEnv.getVariable(paramName);
if (process.env.MLLD_DEBUG === "true") {
logger.debug("Checking parameter:", {
paramName,
hasParamVar: !!paramVar,
paramVarType: paramVar?.type,
isPipelineInput: paramVar?.type === "pipeline-input"
});
}
if (paramVar && paramVar.type === "pipeline-input") {
codeParams[paramName] = paramVar.value;
} else if (paramVar) {
if (definition.language === "bash" || definition.language === "sh") {
const rawValue = paramVar.v