/* RFC-0580: commitWerkstattSideEffects — auto-commit werkstatt-level side-effect files from mission lifecycle commands to the monorepo working tree. Does not push — werkstatt monorepo push is a separate operator-controlled operation. Does not commit bordbuch — bordbuch commits go to the cache clone via commitAndPushBordbuch. RFC-0580: initial commitWerkstattSideEffects helper. RFC-1149: migrate ambient filesystem and process IO to the WorkspaceIO port across engine and shared */ import { gitExec } from "./git-exec.ts"; import { createDefaultIO, type WorkspaceIO } from "@warpgogol/werkstatt-shared/kernel/workspace-io"; export interface CommitWerkstattResult { committed: boolean; commitSha: string | null; } export async function commitWerkstattSideEffects( workspaceRoot: string, files: string[], message: string, io: WorkspaceIO = createDefaultIO().io, ): Promise { for (const file of files) { await gitExec(workspaceRoot, `add -- ${JSON.stringify(file)}`, { allowNonZero: true }); } let hasStagedChanges: boolean; try { const diffResult = await io.exec("sh", ["-c", "git diff --cached --quiet"], { cwd: workspaceRoot, timeoutMs: 30_000, }); hasStagedChanges = diffResult.exitCode !== 0; } catch { hasStagedChanges = true; } if (!hasStagedChanges) { return { committed: false, commitSha: null }; } await gitExec(workspaceRoot, `commit -m ${JSON.stringify(message)}`, { env: { ...process.env, ECOSYSTEM_COMMIT: "1" }, }); const commitSha = await gitExec(workspaceRoot, "rev-parse HEAD"); return { committed: true, commitSha }; }