89 lines
4.1 KiB
JavaScript
89 lines
4.1 KiB
JavaScript
import { z } from "zod";
|
|
import axios from "axios";
|
|
import path from "path";
|
|
import { withAuth, getSessionCredentials } from "../../auth/index.js";
|
|
import { handleToolError, validateRequired } from "../helpers/errorHandler.js";
|
|
import { withAuthParams } from "../helpers/authSchema.js";
|
|
import { LOCAL_SERVER_URL } from "../../config/index.js";
|
|
import { resolveCurrentAcaiUser } from "../helpers/sessionHelpers.js";
|
|
|
|
export function registerCompileModuleTool(server) {
|
|
server.tool(
|
|
"compile_module",
|
|
`Manually recompile a module or general section when generated files may be out of sync and you need to force compilation without editing index-base.tpl.
|
|
Do not use this as part of the normal editing flow: most index-base.tpl edits made through the Acai file tools compile automatically.
|
|
This is a recovery / resync tool, not a required step after routine changes.
|
|
It parses the HTML into Twig, generates builder vars, and syncs with the Docker CMS.
|
|
|
|
Pass the full path to the index-base.tpl file and the project directory.`,
|
|
withAuthParams({
|
|
filePath: z.string().describe("Full absolute path to the index-base.tpl file that was edited"),
|
|
projectDir: z.string().describe("Full absolute path to the project root directory"),
|
|
}),
|
|
{ readOnlyHint: false, destructiveHint: false },
|
|
withAuth(async ({ filePath, projectDir }, extra) => {
|
|
try {
|
|
const validationError = validateRequired(
|
|
{ filePath, projectDir },
|
|
['filePath', 'projectDir'],
|
|
'compile_module'
|
|
);
|
|
if (validationError) return validationError;
|
|
|
|
const normalizedProjectDir = path.resolve(projectDir);
|
|
const normalizedFilePath = path.resolve(filePath);
|
|
const projectSlug = path.basename(normalizedProjectDir);
|
|
const relativePath = path.relative(normalizedProjectDir, normalizedFilePath);
|
|
const canUseSlugMode =
|
|
!!projectSlug &&
|
|
!!relativePath &&
|
|
relativePath !== "" &&
|
|
!relativePath.startsWith("..") &&
|
|
!path.isAbsolute(relativePath);
|
|
|
|
const payload = canUseSlugMode
|
|
? { project: projectSlug, relativePath, project_dir: projectDir }
|
|
: { file: filePath, project_dir: projectDir };
|
|
|
|
// Call the Python server compile endpoint. Inyectar X-Acai-User
|
|
// cuando hay sesion HTTP activa para que el endpoint autenticado
|
|
// resuelva el proyecto dentro de /opt/acai/webs/<user>/.
|
|
const acaiUser = resolveCurrentAcaiUser();
|
|
const headers = { "Content-Type": "application/json" };
|
|
if (acaiUser) headers["X-Acai-User"] = acaiUser;
|
|
const response = await axios.post(
|
|
`${LOCAL_SERVER_URL}/api/compile-module`,
|
|
payload,
|
|
{ headers, timeout: 30000 }
|
|
);
|
|
|
|
if (response.data?.ok) {
|
|
return {
|
|
content: [{
|
|
type: "text",
|
|
text: JSON.stringify({
|
|
success: true,
|
|
message: "Module compiled successfully",
|
|
output: response.data.output || "",
|
|
}, null, 2)
|
|
}],
|
|
};
|
|
} else {
|
|
return {
|
|
content: [{
|
|
type: "text",
|
|
text: JSON.stringify({
|
|
success: false,
|
|
error: response.data?.error || "Compilation failed",
|
|
}, null, 2)
|
|
}],
|
|
isError: true,
|
|
};
|
|
}
|
|
} catch (error) {
|
|
return handleToolError(error, 'compile_module', { filePath, projectDir });
|
|
}
|
|
})
|
|
);
|
|
}
|