Advanced Topics
Advanced configuration patterns for complex setups.
Custom Asset Selection
Section titled “Custom Asset Selection”For non-standard release naming, use assetSelector:
export default defineTool((install) => install("github-release", { repo: "owner/tool", assetSelector: ({ assets, systemInfo, release, log }) => { const osMap: Record<string, string> = { darwin: "macos", linux: "linux" }; const archMap: Record<string, string> = { x64: "amd64", arm64: "arm64" };
return assets.find( (a) => a.name.includes(osMap[systemInfo.platform]) && a.name.includes(archMap[systemInfo.arch]) && a.name.endsWith(".tar.gz"), ); }, }).bin("tool"),);Dynamic Configuration
Section titled “Dynamic Configuration”Use environment variables for runtime configuration:
const isDev = process.env.NODE_ENV === "development";
export default defineTool((install) => install("github-release", { repo: "owner/tool" }) .bin("tool") .version(isDev ? "latest" : "v1.2.3") .zsh((shell) => shell.env({ TOOL_LOG_LEVEL: isDev ? "debug" : "info" })),);Conditional Installation
Section titled “Conditional Installation”Choose methods based on system capabilities:
export default defineTool((install) => { if (process.platform === "darwin" && process.env.HOMEBREW_PREFIX) { return install("brew", { formula: "tool" }).bin("tool"); } return install("github-release", { repo: "owner/tool" }).bin("tool");});Build from Source
Section titled “Build from Source”export default defineTool((install) => install("github-release", { repo: "owner/tool" }) .bin("tool") .hook("after-extract", async ({ extractDir, stagingDir, $ }) => { if (extractDir && stagingDir) { await $`cd ${extractDir} && ./configure --prefix=${stagingDir}`; await $`cd ${extractDir} && make -j$(nproc)`; await $`cd ${extractDir} && make install`; } }),);Dependency Verification
Section titled “Dependency Verification”Combine .dependsOn() with hooks for version checks:
export default defineTool((install) => install("github-release", { repo: "owner/tool" }) .bin("tool") .dependsOn("node") .hook("before-install", async ({ log, $ }) => { const result = await $`node --version`.nothrow(); if (result.exitCode !== 0) { throw new Error("Node is required but not available"); } log.info(`Using Node ${result.stdout.toString().trim()}`); }),);Lazy Loading
Section titled “Lazy Loading”export default defineTool((install, ctx) => install("github-release", { repo: "owner/tool" }) .bin("tool") .zsh((shell) => shell.always(` function expensive-fn() { unfunction expensive-fn source "${ctx.currentDir}/expensive.zsh" expensive-fn "$@" } `), ),);Dynamic Completions
Section titled “Dynamic Completions”export default defineTool((install, ctx) => install("github-release", { repo: "owner/tool" }) .bin("tool") .zsh((shell) => shell .once( ` tool completion zsh > "${ctx.projectConfig.paths.generatedDir}/completions/_tool" `, ) .completions(`${ctx.projectConfig.paths.generatedDir}/completions/_tool`), ),);Parallel Setup Tasks
Section titled “Parallel Setup Tasks”export default defineTool((install) => install("github-release", { repo: "owner/tool" }) .bin("tool") .hook("after-install", async ({ $, log }) => { await Promise.all([$`tool setup-task-1`, $`tool setup-task-2`, $`tool setup-task-3`]); log.info("All setup tasks completed"); }),);