feat: auto-approve — commit + deploy on session completion

- SessionRunOptions: autoApprove, giteaRepo, repoRoot, coolifyAppUuid/Url/Token
- autoCommitAndDeploy(): git add -A, commit with "agent: <task>", push,
  trigger Coolify deploy, PATCH session → approved
- Falls back to done status if commit fails so manual approve still works
- /agent/execute: captures repoRoot before appPath scoping, defaults
  autoApprove to true, passes coolify params from env
- System prompt: "do NOT commit" → "platform handles committing"

Made-with: Cursor
This commit is contained in:
2026-03-07 13:17:25 -08:00
parent 551fdb9e54
commit 214e8c1037
2 changed files with 106 additions and 9 deletions

View File

@@ -359,14 +359,19 @@ app.post('/webhook/gitea', (req: Request, res: Response) => {
const activeSessions = new Map<string, { stopped: boolean }>();
app.post('/agent/execute', async (req: Request, res: Response) => {
const { sessionId, projectId, appName, appPath, giteaRepo, task, continueTask } = req.body as {
const {
sessionId, projectId, appName, appPath, giteaRepo, task, continueTask,
autoApprove, coolifyAppUuid,
} = req.body as {
sessionId?: string;
projectId?: string;
appName?: string;
appPath?: string;
giteaRepo?: string;
task?: string;
continueTask?: string; // if set, appended as follow-up to the original task
continueTask?: string;
autoApprove?: boolean;
coolifyAppUuid?: string;
};
if (!sessionId || !projectId || !appPath || !task) {
@@ -400,6 +405,9 @@ app.post('/agent/execute', async (req: Request, res: Response) => {
return;
}
// Capture repo root before scoping to appPath — needed for git commit in auto-approve
const repoRoot = ctx.workspaceRoot;
// Scope workspace to the app subdirectory so the agent works there naturally
if (appPath) {
const path = require('path') as typeof import('path');
@@ -431,7 +439,13 @@ app.post('/agent/execute', async (req: Request, res: Response) => {
projectId,
vibnApiUrl,
appPath,
repoRoot,
isStopped: () => sessionState.stopped,
autoApprove: autoApprove ?? true,
giteaRepo,
coolifyAppUuid,
coolifyApiUrl: process.env.COOLIFY_API_URL,
coolifyApiToken: process.env.COOLIFY_API_TOKEN,
})
.catch(err => {
const msg = err instanceof Error ? err.message : String(err);