diff --git a/packages/cli/src/commands/init.ts b/packages/cli/src/commands/init.ts index 3917b1a84..61917e2b9 100644 --- a/packages/cli/src/commands/init.ts +++ b/packages/cli/src/commands/init.ts @@ -196,29 +196,26 @@ function transcodeToMp4(inputPath: string, outputPath: string): Promise // Static template helpers // --------------------------------------------------------------------------- -function getStaticTemplateDir(templateId: string): string { - const dir = dirname(fileURLToPath(import.meta.url)); - // In dev: cli/src/commands/ → ../templates = cli/src/templates/ - // In built: cli/dist/ → templates = cli/dist/templates/ - const devPath = resolve(dir, "..", "templates", templateId); - const builtPath = resolve(dir, "templates", templateId); +/** Resolve an asset directory that differs between dev (src/) and built (dist/). */ +function resolveAssetDir(devSegments: string[], builtSegments: string[]): string { + const base = dirname(fileURLToPath(import.meta.url)); + const devPath = resolve(base, ...devSegments); + const builtPath = resolve(base, ...builtSegments); return existsSync(devPath) ? devPath : builtPath; } +function getStaticTemplateDir(templateId: string): string { + return resolveAssetDir(["..", "templates", templateId], ["templates", templateId]); +} + function getSharedTemplateDir(): string { - const dir = dirname(fileURLToPath(import.meta.url)); - const devPath = resolve(dir, "..", "templates", "_shared"); - const builtPath = resolve(dir, "templates", "_shared"); - return existsSync(devPath) ? devPath : builtPath; + return resolveAssetDir(["..", "templates", "_shared"], ["templates", "_shared"]); } function getBundledSkillsDir(): string { - const dir = dirname(fileURLToPath(import.meta.url)); - // In dev: cli/src/commands/ → ../../../../skills = repo root skills/ - // In built: cli/dist/ → skills = cli/dist/skills/ - const devPath = resolve(dir, "..", "..", "..", "..", "skills"); - const builtPath = resolve(dir, "skills"); - return existsSync(devPath) ? devPath : builtPath; + // In dev: cli/src/commands/ → repo root skills/ + // In built: cli/dist/ → cli/dist/skills/ + return resolveAssetDir(["..", "..", "..", "..", "skills"], ["skills"]); } function patchVideoSrc( diff --git a/packages/cli/src/commands/install-skills.ts b/packages/cli/src/commands/install-skills.ts index de0c48d35..e5801059d 100644 --- a/packages/cli/src/commands/install-skills.ts +++ b/packages/cli/src/commands/install-skills.ts @@ -202,15 +202,20 @@ function fallbackInstall(targets: Target[]): { } } + // Install to first target and collect results, then copy to remaining targets + const [first, ...rest] = targets; const allInstalled: InstalledSkill[] = []; - let counted = false; - for (const target of targets) { + if (first) { + mkdirSync(first.dir, { recursive: true }); + for (const { skillsDir, source } of fetched) { + allInstalled.push(...installSkillsFromDir(skillsDir, first.dir, source.name)); + } + } + for (const target of rest) { mkdirSync(target.dir, { recursive: true }); for (const { skillsDir, source } of fetched) { - const skills = installSkillsFromDir(skillsDir, target.dir, source.name); - if (!counted) allInstalled.push(...skills); + installSkillsFromDir(skillsDir, target.dir, source.name); } - counted = true; } return { count: allInstalled.length, installed: allInstalled, skipped }; @@ -301,12 +306,10 @@ async function runInstall({ args }: { args: Record }): Promise< if (installed.length > 0) { clack.outro(c.success(`${installed.join(" + ")} skills installed.`)); - } else { - clack.log.warn("npx skills add failed — trying fallback..."); - // Fall through to git fallback below + return; } - if (installed.length > 0) return; + clack.log.warn("npx skills add failed — trying fallback..."); } // Fallback: git clone + copy