#!/usr/bin/env runts -- --allow-all import {parseArgs} from "jsr:@std/cli/parse-args"; import {execCommandShell, log, ProcessBar, term,} from "https://script.hatter.ink/@61/deno-commons-mod.ts"; import {summarizeGitStatusDiff} from "https://script.hatter.ink/@0/deno-ai-mod.ts"; import {getGitLocalRev, getGitRemoteRev, getGitStatus,} from "https://script.hatter.ink/@2/deno-git-mod.ts"; async function checkRev(): Promise { const localRev = await getGitLocalRev(); const remoteRev = await new ProcessBar("Checking rev").call( async (): Promise => { return await getGitRemoteRev(); }, ); if (localRev === remoteRev) { console.log(term.green(`Check rev successfully, rev: ${localRev}`)); } else { throw `Check rev failed, local rev: ${localRev} vs remote rev: ${remoteRev}`; } } async function main() { const flags = parseArgs(Deno.args, { boolean: ["help", "check-only", "auto-commit"], alias: { H: "help", C: "check-only", A: "auto-commit", }, }); const checkOnly = flags["check-only"]; const autoCommit = flags["auto-commit"]; if (flags.help) { console.log(`commit.ts commit.ts [-H|--help] - show help message commit.ts [-C|--check-only] - check rev and status only commit.ts [-A|--auto-commit] - auto commit with AI summarize `); return; } await checkRev(); // check local rev <--> remote rev equals const gitStatus = await getGitStatus(); if (gitStatus === null) { log.warn("No git status found"); return; } log.info("Git status:", gitStatus); if (checkOnly) { log.info("Check only, skip commit."); return; } const summary = await new ProcessBar("AI summarizing").call( async (): Promise => { return await summarizeGitStatusDiff(); }, ); if (summary != null) { log.success(`AI summarized git commit message: ${summary}`); } let emptyCount = 0; let message = "empty message"; if (autoCommit && summary) { message = summary; } else { do { if (emptyCount++ === 3) { readline.close(); console.log("Too many empty messages, then exit"); return; } message = prompt( "Input your commit message (Enter for AI summary) > ", ); if (message.trim().length == 0) { message = summary ?? ""; } } while (message.length == 0); } const gitCommitArgs: string[] = []; gitCommitArgs.push("commit"); for (const file of gitStatus.modified) { gitCommitArgs.push(file); } for (const file of gitStatus.deleted) { gitCommitArgs.push(file); } for (const file of gitStatus.untracked) { gitCommitArgs.push(file); } gitCommitArgs.push("-m"); gitCommitArgs.push(message); if (gitStatus.untracked.length > 0) { const gitAddArgs = ["add"]; for (const file of gitStatus.untracked) { gitAddArgs.push(file); } log.info(">>>>>", ["git", gitAddArgs]); await execCommandShell("git", gitAddArgs); } log.info(">>>>>", ["git", gitCommitArgs]); await execCommandShell("git", gitCommitArgs); log.info(">>>>>", ["git", "push"]); await new ProcessBar("Git pushing").call(async (): Promise => { await execCommandShell("git", ["push"]); }); } main().catch((err) => { log.error(err); process.exit(0); }).then(() => process.exit(0)); // @SCRIPT-SIGNATURE-V1: yk-r1.ES256.20260412T103218+08:00.MEQCIHiNlGec5h1nMm8DdzCY // dmCVLfihKXkov+AmLoTwSU+wAiBmt279SHXXYxMEOWeXuyq/is77Dnk1BBMbWXUswqFAJQ==