feat: add semantic-release for automated versioning and help dialog

- Set up semantic-release with zero-touch CI pipeline on push to main
- Add version sync script to keep all package.json files and APP_VERSION
  constant in sync automatically
- Consolidate Docker publishing into single tag-triggered workflow that
  pushes to both Docker Hub and ghcr.io with semver tags
- Add help dialog with keyboard shortcuts, getting started guide, and
  resource links
- Sync all versions to 0.2.1 to match Docker Hub latest
This commit is contained in:
Siddharth Kumar Sah
2026-03-22 21:25:14 +08:00
parent fb1d366d5f
commit 4807bd2726
22 changed files with 2359 additions and 82 deletions
+25 -15
View File
@@ -1,6 +1,8 @@
import { runPythonScript } from "./bridge.js";
import { writeFile, readFile } from "node:fs/promises";
import { writeFile, readFile, unlink } from "node:fs/promises";
import { join } from "node:path";
import { tmpdir } from "node:os";
import { randomUUID } from "node:crypto";
export interface RemoveBackgroundOptions {
model?: string;
@@ -12,22 +14,30 @@ export async function removeBackground(
outputDir: string,
options: RemoveBackgroundOptions = {},
): Promise<Buffer> {
const inputPath = join(outputDir, "input_bg.png");
const outputPath = join(outputDir, "output_bg.png");
const id = randomUUID();
const inputPath = join(tmpdir(), `rembg_in_${id}.png`);
const outputPath = join(outputDir, `rembg_out_${id}.png`);
await writeFile(inputPath, inputBuffer);
// BiRefNet models need longer timeout (up to 10 min for first load)
const timeout = options.model?.startsWith("birefnet") ? 600000 : 300000;
const { stdout } = await runPythonScript("remove_bg.py", [
inputPath,
outputPath,
JSON.stringify(options),
], timeout);
try {
// BiRefNet models need longer timeout (up to 10 min for first load)
const timeout = options.model?.startsWith("birefnet") ? 600000 : 300000;
const { stdout } = await runPythonScript("remove_bg.py", [
inputPath,
outputPath,
JSON.stringify(options),
], timeout);
const result = JSON.parse(stdout);
if (!result.success) {
throw new Error(result.error || "Background removal failed");
const result = JSON.parse(stdout);
if (!result.success) {
throw new Error(result.error || "Background removal failed");
}
const outputBuffer = await readFile(outputPath);
return outputBuffer;
} finally {
// Clean up temp files
await unlink(inputPath).catch(() => {});
await unlink(outputPath).catch(() => {});
}
return readFile(outputPath);
}