From 909189b74594ec6fb2215037209d0b8be4f0c05a Mon Sep 17 00:00:00 2001 From: Chris Wanstrath Date: Mon, 23 Feb 2026 20:33:10 -0800 Subject: [PATCH] Extract browse HTML into external template The HTML for the browse view was inlined as a template literal in browse.ts, making it hard to edit and losing syntax highlighting. Move it to browse.html and use placeholder replacement instead. Also update branchDiff to accept the main branch as a parameter so the caller resolves it once and reuses it for diffStat too. --- src/commands/browse.html | 60 +++++++++++++++++++++++++++++++++ src/commands/browse.ts | 73 +++++----------------------------------- src/git.ts | 3 +- 3 files changed, 70 insertions(+), 66 deletions(-) create mode 100644 src/commands/browse.html diff --git a/src/commands/browse.html b/src/commands/browse.html new file mode 100644 index 0000000..c2fbef9 --- /dev/null +++ b/src/commands/browse.html @@ -0,0 +1,60 @@ + + + + +{{BRANCH}} — sandlot diff + + + + +
+

{{BRANCH}}

+ {{PROMPT_SECTION}} +
+ {{LOG_SECTION}} + {{STAT_SECTION}} +
+
+
+ + + + diff --git a/src/commands/browse.ts b/src/commands/browse.ts index eb474e8..ebf69ac 100644 --- a/src/commands/browse.ts +++ b/src/commands/browse.ts @@ -3,13 +3,15 @@ import * as git from "../git.ts" import { die } from "../fmt.ts" import { requireSession } from "./helpers.ts" +const template = await Bun.file(new URL("browse.html", import.meta.url).pathname).text() + export async function action(branch: string) { const { session } = await requireSession(branch) const worktree = session.worktree const main = await git.mainBranch(worktree) const [diff, log, stat] = await Promise.all([ - git.branchDiff(branch, worktree), + git.branchDiff(branch, main, worktree), git.commitLog(`${main}..${branch}`, worktree), git.diffStat(`${main}...${branch}`, worktree), ]) @@ -18,69 +20,12 @@ export async function action(branch: string) { die(`No changes on branch "${branch}" compared to ${main}.`) } - const prompt = session.prompt ? escapeHtml(session.prompt) : "" - const diffJson = JSON.stringify(diff) - - const html = ` - - - -${escapeHtml(branch)} — sandlot diff - - - - -
-

${escapeHtml(branch)}

- ${prompt ? `

${prompt}

` : ""} -
- ${log ? `

Commits

${escapeHtml(log)}
` : ""} - ${stat ? `

Stats

${escapeHtml(stat)}
` : ""} -
-
-
- - - -` + const html = template + .replaceAll("{{BRANCH}}", escapeHtml(branch)) + .replace("{{PROMPT_SECTION}}", session.prompt ? `

${escapeHtml(session.prompt)}

` : "") + .replace("{{LOG_SECTION}}", log ? `

Commits

${escapeHtml(log)}
` : "") + .replace("{{STAT_SECTION}}", stat ? `

Stats

${escapeHtml(stat)}
` : "") + .replace("{{DIFF_JSON}}", JSON.stringify(diff)) const tmpPath = `/tmp/sandlot-browse-${branch}.html` await Bun.write(tmpPath, html) diff --git a/src/git.ts b/src/git.ts index 21cf5d3..417d86c 100644 --- a/src/git.ts +++ b/src/git.ts @@ -219,8 +219,7 @@ export async function hasNewCommits(worktreePath: string): Promise { } /** Get the full unified diff of a branch vs main as a string. */ -export async function branchDiff(branch: string, cwd: string): Promise { - const main = await mainBranch(cwd) +export async function branchDiff(branch: string, main: string, cwd: string): Promise { const result = await $`git diff ${main}...${branch}`.cwd(cwd).nothrow().quiet() if (result.exitCode !== 0) return "" return result.text()