UNPKG

@jovan158/vantage

Version:

See and control what your coding agent does

84 lines (83 loc) • 3.4 kB
// `vantage review` and `vantage discard`: what a session changed, and // dropping an isolated session's branch. import fs from "node:fs"; import path from "node:path"; import { sessionDir } from "../events.js"; import { gitSafe, removeSessionWorktree, treeDiff } from "../git.js"; import { readMeta } from "../session-meta.js"; import { log, fmtFileLine } from "./output.js"; export async function cmdReview(argv) { const showPatch = argv.includes("--patch") || argv.includes("-p"); const sessionId = argv.find((a) => !a.startsWith("-")); if (!sessionId) { log("usage: vantage review <sessionId> [--patch]"); return 1; } const cwd = process.cwd(); const meta = readMeta(cwd, sessionId); if (!meta) { log(`no session "${sessionId}" found under .vantage/sessions/`); return 1; } // Not isolated: the working-tree snapshots from start and end. if (!meta.isolated) { if (!meta.startTree || !meta.endTree) { log(`no change record for session ${sessionId} (not a git repository, still running, or started before change tracking)`); return 1; } const diff = treeDiff(cwd, meta.startTree, meta.endTree); if (diff.files.length === 0) { log(`no files changed during session ${sessionId}`); return 0; } if (showPatch) { process.stdout.write(diff.patch + "\n"); return 0; } log(`changed during session ${sessionId}: ${diff.files.length} file(s), +${diff.added}/-${diff.removed} (edits made meanwhile included)`); for (const f of diff.files) process.stdout.write(fmtFileLine(f) + "\n"); log(`full diff: vantage review ${sessionId} --patch`); log(`undo them: git diff ${meta.startTree.slice(0, 12)} ${meta.endTree.slice(0, 12)} | git apply -R`); return 0; } if (!meta.branch || !meta.baseSha) { log(`session ${sessionId} has no isolation branch recorded`); return 1; } const branchExists = gitSafe(cwd, ["rev-parse", "--verify", meta.branch]).ok; if (branchExists) { const stat = gitSafe(cwd, ["diff", "--stat", meta.baseSha, meta.branch]); log(`branch ${meta.branch} vs base ${meta.baseSha.slice(0, 8)}:`); process.stdout.write(stat.stdout + "\n"); log(`full diff: git diff ${meta.baseSha.slice(0, 8)} ${meta.branch}`); log(`merge: git merge --no-ff ${meta.branch}`); log(`discard: vantage discard ${sessionId}`); } else { const patch = path.join(sessionDir(cwd, sessionId), "changes.patch"); if (fs.existsSync(patch)) { log(`branch is gone; saved patch: ${patch}`); } else { log(`nothing to review for session ${sessionId}`); } } return 0; } export async function cmdDiscard(argv) { const sessionId = argv[0]; if (!sessionId) { log("usage: vantage discard <sessionId>"); return 1; } const cwd = process.cwd(); const meta = readMeta(cwd, sessionId); if (!meta || !meta.isolated || !meta.branch || !meta.worktreePath) { log(`session ${sessionId} has no isolation worktree to discard`); return 1; } removeSessionWorktree(cwd, meta.worktreePath, meta.branch); log(`discarded worktree and branch ${meta.branch}`); return 0; }