mirror of
https://github.com/snapotter-hq/SnapOtter.git
synced 2026-08-03 07:46:42 +02:00
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:
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@stirling-image/ai",
|
||||
"version": "0.0.1",
|
||||
"version": "0.2.1",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"main": "./src/index.ts",
|
||||
|
||||
@@ -68,10 +68,8 @@ def main():
|
||||
}
|
||||
)
|
||||
)
|
||||
sys.exit(1)
|
||||
except Exception as e:
|
||||
print(json.dumps({"success": False, "error": str(e)}))
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -25,8 +25,8 @@ function extractPythonError(error: unknown): string {
|
||||
stdout?: string;
|
||||
message?: string;
|
||||
};
|
||||
// Try to parse JSON error from stderr or stdout
|
||||
for (const output of [execError.stderr, execError.stdout]) {
|
||||
// Try stdout first (Python scripts write JSON errors there), then stderr
|
||||
for (const output of [execError.stdout, execError.stderr]) {
|
||||
if (output) {
|
||||
try {
|
||||
const parsed = JSON.parse(output.trim());
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
export const AI_VERSION = "0.0.1";
|
||||
|
||||
export { runPythonScript } from "./bridge.js";
|
||||
export { removeBackground } from "./background-removal.js";
|
||||
export type { RemoveBackgroundOptions } from "./background-removal.js";
|
||||
|
||||
Reference in New Issue
Block a user