mirror of
https://github.com/getcompanion-ai/co-mono.git
synced 2026-04-20 13:02:15 +00:00
35 lines
1.1 KiB
TypeScript
35 lines
1.1 KiB
TypeScript
import { execFile } from "node:child_process";
|
|
import fs from "node:fs";
|
|
import path from "node:path";
|
|
import { promisify } from "node:util";
|
|
|
|
const execFileAsync = promisify(execFile);
|
|
|
|
/**
|
|
* Runs a hook script asynchronously if it exists.
|
|
* Hooks are located in .pi/team-hooks/{hookName}.sh relative to the CWD.
|
|
*
|
|
* @param teamName The name of the team.
|
|
* @param hookName The name of the hook to run (e.g., 'task_completed').
|
|
* @param payload The payload to pass to the hook script as the first argument.
|
|
* @returns true if the hook doesn't exist or executes successfully; false otherwise.
|
|
*/
|
|
export async function runHook(teamName: string, hookName: string, payload: any): Promise<boolean> {
|
|
const hookPath = path.join(process.cwd(), ".pi", "team-hooks", `${hookName}.sh`);
|
|
|
|
if (!fs.existsSync(hookPath)) {
|
|
return true;
|
|
}
|
|
|
|
try {
|
|
const payloadStr = JSON.stringify(payload);
|
|
// Use execFile: More secure (no shell interpolation) and asynchronous
|
|
await execFileAsync(hookPath, [payloadStr], {
|
|
env: { ...process.env, PI_TEAM: teamName },
|
|
});
|
|
return true;
|
|
} catch (error) {
|
|
console.error(`Hook ${hookName} failed:`, error);
|
|
return false;
|
|
}
|
|
}
|