video-product-finder/scripts/run.ts

121 lines
4.2 KiB
TypeScript
Raw Normal View History

#!/usr/bin/env bun
import { resolve } from 'path';
import type { Command } from '../src/types.ts';
import { run } from '../src/index.ts';
const SKILL_NAME = 'video-product-snapshot';
// Load .env from skill root (does not override existing env vars)
loadDotenv(resolve(import.meta.dir, '../.env'));
function loadDotenv(path: string): void {
let raw: string;
try { raw = require('fs').readFileSync(path, 'utf-8'); } catch { return; }
for (const line of raw.split('\n')) {
const trimmed = line.trim();
if (!trimmed || trimmed.startsWith('#')) continue;
const eq = trimmed.indexOf('=');
if (eq < 0) continue;
const key = trimmed.slice(0, eq).trim();
const val = trimmed.slice(eq + 1).trim().replace(/^["']|["']$/g, '');
if (key && !(key in process.env)) process.env[key] = val;
}
}
function printUsage(): void {
console.error(`用法:
bun scripts/run.ts [--api-base=<url>] <command> [args...] [--dry-run]
:
session
session token
detect <video-path> [options]
:
--interval=<> 默认: 1
--max-frames=<数量> 默认: 60
--output-dir=<目录> 默认: 视频所在目录
--min-confidence=<0-1> 默认: 0.7
search <image-path>
ecom image-search API
detect-and-search <video-path> [options]
detect-best <video-path> [options]
detect-best-and-search <video-path> [options]
detect-video <video-path>
detect-video-and-search <video-path>
1688
rerank --image-results=<json> [--description=<text>] [--keyword=<text>] [--top=<n>]
: ~/.openclaw/.env (CLIENT_KEY), skill .env (VISION_API_KEY)
`);
}
function reportTelemetry(payload: object): void {
const endpoint = process.env.TELEMETRY_ENDPOINT;
if (!endpoint) return;
fetch(endpoint, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload),
}).catch(() => {});
}
async function main(): Promise<void> {
const positionals: string[] = [];
let dryRun = false;
for (const arg of process.argv.slice(2)) {
if (arg === '--dry-run') {
dryRun = true;
} else if (arg.startsWith('--api-base=')) {
process.env.API_BASE = arg.slice('--api-base='.length).trim();
} else if (arg.startsWith('--session-id=')) {
process.env.SKILL_SESSION_ID = arg.slice('--session-id='.length).trim();
} else if (arg === '-h' || arg === '--help') {
printUsage(); process.exit(0);
} else {
positionals.push(arg);
}
}
if (positionals.length < 1) { printUsage(); process.exit(1); }
const command = positionals[0] as Command;
const sessionId = process.env.SKILL_SESSION_ID!; // set by auth-cli.ts at module load
const startMs = Date.now();
let result: Awaited<ReturnType<typeof run>>;
try {
result = await run(command, positionals.slice(1), dryRun);
} catch (err) {
const error = err instanceof Error ? err.message : String(err);
console.log(JSON.stringify({ status: 'failed', command, dryRun, sessionId, error }, null, 2));
if (!dryRun) reportTelemetry({ skill: SKILL_NAME, command, sessionId, status: 'failed', durationMs: Date.now() - startMs, error });
process.exit(1);
}
const output = { ...result, sessionId } as Record<string, unknown>;
console.log(JSON.stringify(output, null, 2));
if (!dryRun) reportTelemetry({ skill: SKILL_NAME, command, sessionId, status: result.status, durationMs: Date.now() - startMs, error: (result as any).error });
}
main().catch((err) => {
console.error(JSON.stringify({
status: 'failed',
error: err instanceof Error ? err.message : String(err),
}, null, 2));
process.exit(1);
});