* refactor(shared): unify binary downloader and session path storage - Create binary-downloader.ts for common download/extract logic - Create session-injected-paths.ts for unified path tracking - Refactor comment-checker, ast-grep, grep downloaders to use shared util - Consolidate directory injector types into shared module * feat(shared): implement unified model resolution pipeline - Create ModelResolutionPipeline for centralized model selection - Refactor model-resolver to use pipeline - Update delegate-task and config-handler to use unified logic - Ensure consistent model resolution across all agent types * refactor(agents): simplify agent utils and metadata management - Extract helper functions for config merging and env context - Register prompt metadata for all agents - Simplify agent variant detection logic * cleanup: inline utilities and remove unused exports - Remove case-insensitive.ts (inline with native JS) - Simplify opencode-version helpers - Remove unused getModelLimit, createCompactionContextInjector exports - Inline transcript entry creation in claude-code-hooks - Update tests accordingly --------- Co-authored-by: justsisyphus <justsisyphus@users.noreply.github.com>
61 lines
1.8 KiB
TypeScript
61 lines
1.8 KiB
TypeScript
import { chmodSync, existsSync, mkdirSync, unlinkSync } from "node:fs";
|
|
import * as path from "node:path";
|
|
import { spawn } from "bun";
|
|
import { extractZip } from "./zip-extractor";
|
|
|
|
export function getCachedBinaryPath(cacheDir: string, binaryName: string): string | null {
|
|
const binaryPath = path.join(cacheDir, binaryName);
|
|
return existsSync(binaryPath) ? binaryPath : null;
|
|
}
|
|
|
|
export function ensureCacheDir(cacheDir: string): void {
|
|
if (!existsSync(cacheDir)) {
|
|
mkdirSync(cacheDir, { recursive: true });
|
|
}
|
|
}
|
|
|
|
export async function downloadArchive(downloadUrl: string, archivePath: string): Promise<void> {
|
|
const response = await fetch(downloadUrl, { redirect: "follow" });
|
|
if (!response.ok) {
|
|
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
|
|
}
|
|
|
|
const arrayBuffer = await response.arrayBuffer();
|
|
await Bun.write(archivePath, arrayBuffer);
|
|
}
|
|
|
|
export async function extractTarGz(
|
|
archivePath: string,
|
|
destDir: string,
|
|
options?: { args?: string[]; cwd?: string }
|
|
): Promise<void> {
|
|
const args = options?.args ?? ["tar", "-xzf", archivePath, "-C", destDir];
|
|
const proc = spawn(args, {
|
|
cwd: options?.cwd,
|
|
stdout: "pipe",
|
|
stderr: "pipe",
|
|
});
|
|
|
|
const exitCode = await proc.exited;
|
|
if (exitCode !== 0) {
|
|
const stderr = await new Response(proc.stderr).text();
|
|
throw new Error(`tar extraction failed (exit ${exitCode}): ${stderr}`);
|
|
}
|
|
}
|
|
|
|
export async function extractZipArchive(archivePath: string, destDir: string): Promise<void> {
|
|
await extractZip(archivePath, destDir);
|
|
}
|
|
|
|
export function cleanupArchive(archivePath: string): void {
|
|
if (existsSync(archivePath)) {
|
|
unlinkSync(archivePath);
|
|
}
|
|
}
|
|
|
|
export function ensureExecutable(binaryPath: string): void {
|
|
if (process.platform !== "win32" && existsSync(binaryPath)) {
|
|
chmodSync(binaryPath, 0o755);
|
|
}
|
|
}
|