Files
shockbot/utils/lifecycle.ts
T
pullfrog[bot] 1d59fd3d21 feat: Lifecycle hooks (#219)
* flatten lifecycle hooks into RepoSettings string fields

replace the separate LifecycleHook model with setupScript and
postCheckoutScript string fields directly on RepoSettings. move the UI
into the Agent settings section alongside environment variables and
custom instructions. delete the standalone lifecycle-hooks API route,
component, and schema since the existing settings PATCH endpoint
handles the new fields automatically.

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix: pass env to lifecycle hook spawn so scripts can use package managers

Co-authored-by: Cursor <cursoragent@cursor.com>

---------

Co-authored-by: Colin McDonnell <colinmcd94@gmail.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-06 07:16:14 +00:00

38 lines
1.1 KiB
TypeScript

import { LIFECYCLE_HOOK_TIMEOUT_MS } from "../lifecycle.ts";
import { log } from "./cli.ts";
import { spawn } from "./subprocess.ts";
export interface ExecuteLifecycleHookParams {
event: string;
script: string | null;
}
/**
* execute a lifecycle hook script if one is configured.
* runs the script in a bash shell with a timeout.
*/
export async function executeLifecycleHook(params: ExecuteLifecycleHookParams): Promise<void> {
if (!params.script) return;
log.info(`» executing ${params.event} lifecycle hook...`);
const result = await spawn({
cmd: "bash",
args: ["-c", params.script],
env: process.env,
timeout: LIFECYCLE_HOOK_TIMEOUT_MS,
activityTimeout: 0,
onStdout: (chunk) => process.stdout.write(chunk),
onStderr: (chunk) => process.stderr.write(chunk),
});
if (result.exitCode !== 0) {
const output = result.stderr || result.stdout;
throw new Error(
`lifecycle hook '${params.event}' failed with exit code ${result.exitCode}:\n${output}`
);
}
log.info(`» ${params.event} lifecycle hook completed successfully`);
}