//#region src/agent/workflow/lint.ts
const LINT_TARGETS = new Set([
	"agent",
	"parallel",
	"pipeline"
]);
function lintAwaits(ast) {
	walk(ast, null, (node, parent) => {
		if (!isLintTarget(node)) return;
		if (isAcceptableParent(parent, node)) return;
		const calleeName = node.callee.name;
		const line = node.loc?.start.line ?? "?";
		throw new Error(formatError(calleeName, line, parent));
	});
}
function isLintTarget(node) {
	if (node.type !== "CallExpression") return false;
	const callee = node.callee;
	if (!callee || callee.type !== "Identifier") return false;
	return LINT_TARGETS.has(callee.name);
}
function isAcceptableParent(parent, call) {
	if (!parent) return false;
	switch (parent.type) {
		case "AwaitExpression": return parent.argument === call;
		case "ReturnStatement": return parent.argument === call;
		case "ExpressionStatement": return parent.expression === call;
		case "ArrowFunctionExpression": return parent.expression === true && parent.body === call;
		default: return false;
	}
}
function formatError(name, line, parent) {
	const ctx = parentContextHint(parent);
	return [
		`workflow lint error at line ${line}: \`${name}(...)\` returns a Promise but is used without 'await'${ctx ? ` (${ctx})` : ""}.`,
		`  ❌ const x = ${name}(...); x.map(...)`,
		`  ✅ const x = await ${name}(...); x.map(...)`,
		`Workflow scripts run in an async IIFE — 'await' parallel()/pipeline()/agent() before using their results, or 'return' them directly.`
	].join("\n");
}
function parentContextHint(parent) {
	if (!parent) return "";
	switch (parent.type) {
		case "VariableDeclarator": return "assigned to variable";
		case "AssignmentExpression": return "assigned via =";
		case "MemberExpression": return "method/property access on Promise";
		case "TemplateLiteral": return "interpolated in template string";
		case "BinaryExpression":
		case "LogicalExpression": return "used in expression";
		case "ConditionalExpression": return "used as ternary operand";
		case "CallExpression": return "passed as argument";
		case "Property": return "used as object property value";
		case "ArrayExpression": return "placed in array (use a thunk: () => call)";
		case "SpreadElement": return "spread";
		case "IfStatement":
		case "WhileStatement":
		case "DoWhileStatement":
		case "ForStatement": return "used as condition";
		default: return parent.type;
	}
}
function walk(node, parent, visit) {
	visit(node, parent);
	for (const value of Object.values(node)) if (Array.isArray(value)) {
		for (const v of value) if (isAstNode(v)) walk(v, node, visit);
	} else if (isAstNode(value)) walk(value, node, visit);
}
function isAstNode(value) {
	return !!value && typeof value === "object" && typeof value.type === "string";
}
//#endregion
export { lintAwaits };

//# sourceMappingURL=lint.js.map