feat(FN-692): add setupScript setting for automatic worktree initialization
- Add `setupScript` property to ProjectSettings to reference a named script - Execute the referenced setup script after worktreeInitCommand on fresh worktrees - Log success/failure of setup script execution; warn and skip if script name not found - Skip setup script for pooled/recycled worktrees (fresh only) - Add changeset (minor) for the new setting
This commit is contained in:
@@ -673,6 +673,12 @@ export interface ProjectSettings {
|
||||
* Key is the script name, value is the shell command to execute.
|
||||
* Script names must be alphanumeric with hyphens and underscores only. */
|
||||
scripts?: Record<string, string>;
|
||||
/** Name of a script from the `scripts` map to run automatically when
|
||||
* fresh worktrees are created. Runs after `worktreeInitCommand` (if both
|
||||
* are configured). Has no effect on pooled/recycled worktrees.
|
||||
* If the referenced script doesn't exist, a warning is logged and
|
||||
* the task continues. */
|
||||
setupScript?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -739,6 +745,7 @@ export const DEFAULT_PROJECT_SETTINGS: ProjectSettings = {
|
||||
titleSummarizerProvider: undefined,
|
||||
titleSummarizerModelId: undefined,
|
||||
scripts: {},
|
||||
setupScript: undefined,
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -802,6 +809,7 @@ export const PROJECT_SETTINGS_KEYS: ReadonlyArray<keyof ProjectSettings> = [
|
||||
"titleSummarizerProvider",
|
||||
"titleSummarizerModelId",
|
||||
"scripts",
|
||||
"setupScript",
|
||||
] as const;
|
||||
|
||||
export interface BoardConfig {
|
||||
|
||||
@@ -448,6 +448,26 @@ export class TaskExecutor {
|
||||
await this.store.logEntry(task.id, `Worktree init command failed: ${message}`);
|
||||
}
|
||||
}
|
||||
|
||||
// Run setup script for fresh worktrees (after worktreeInitCommand)
|
||||
if (settings.setupScript) {
|
||||
const scriptCommand = settings.scripts?.[settings.setupScript];
|
||||
if (scriptCommand) {
|
||||
try {
|
||||
execSync(scriptCommand, {
|
||||
cwd: worktreePath,
|
||||
stdio: "pipe",
|
||||
timeout: 120_000,
|
||||
});
|
||||
await this.store.logEntry(task.id, `Setup script '${settings.setupScript}' completed`, scriptCommand);
|
||||
} catch (err: any) {
|
||||
const message = err.stderr?.toString() || err.message || "Unknown error";
|
||||
await this.store.logEntry(task.id, `Setup script '${settings.setupScript}' failed: ${message}`);
|
||||
}
|
||||
} else {
|
||||
await this.store.logEntry(task.id, `Setup script '${settings.setupScript}' not found in scripts map — skipping`);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (task.worktree) {
|
||||
// Task already had a worktree assigned and it exists on disk — reuse it
|
||||
|
||||
Reference in New Issue
Block a user