framework
Version:
The (AI) Framework: turnkey, zero-config AI orchestration that wraps a coding-agent CLI (Claude Code) as a black box and takes you from an idea to a running app. Vite for AI.
37 lines • 1.57 kB
JavaScript
import { nodeGitRunner } from '../project.js';
/** Strip git's surrounding quotes from a path with special chars (basic; leaves escapes as-is). */
function unquotePath(path) {
return path.length >= 2 && path.startsWith('"') && path.endsWith('"') ? path.slice(1, -1) : path;
}
/** Parse `git status --porcelain` output. Shared with the handoff's pending-files read (#1173). */
export function parsePorcelain(out) {
const entries = [];
for (const line of out.split('\n')) {
if (line.length < 4)
continue;
const code = line.slice(0, 2);
let path = line.slice(3);
const arrow = path.indexOf(' -> ');
if (arrow !== -1)
path = path.slice(arrow + 4); // a rename: the new path is the one that exists
path = unquotePath(path);
if (!path)
continue;
entries.push({ code, path });
}
return entries;
}
/**
* Read each changed file's status from `git status --porcelain`, keyed by repo-relative path.
* `??` is untracked, a `D` in either column is deleted, anything else (M/A/R/C…) reads as
* modified. Renames map to the new path. Returns `{}` when the path is not a git repo.
*/
export async function readFileStatuses(cwd, git = nodeGitRunner()) {
const out = await git(['status', '--porcelain'], cwd).catch(() => '');
const map = {};
for (const { code, path } of parsePorcelain(out)) {
map[path] = code === '??' ? 'untracked' : code.includes('D') ? 'deleted' : 'modified';
}
return map;
}
//# sourceMappingURL=file-status.js.map