fix(cli): install skills into project dir on non-interactive init (#1671)

`hyperframes init` only installed AI coding skills on the interactive path
(behind a clack confirm). When an agent drives it non-interactively (no TTY),
it just printed `npx skills add ...` and returned — so skills were never
installed and the agent later hit `Unknown skill: <workflow>`.

- init: both interactive and non-interactive branches now run
  `npx skills add` with `cwd` set to the new project dir so skills land
  there, not in the caller's working directory. Non-interactive additionally
  passes `--yes`; when Claude Code is driving (CLAUDECODE env var), adds
  `--agent claude-code` so skills target `.claude/skills/`.
- skills: `runSkillsAdd` accepts `cwd` and `extraArgs` so callers can
  control where and how skills are installed.
- templates: CLAUDE.md / AGENTS.md now tell agents to run
  `npx skills add heygen-com/hyperframes` to install or update skills.

Co-authored-by: Wenbo Zhu <295860553+kiritowoo@users.noreply.github.com>
This commit is contained in:
Miguel Ángel
2026-06-23 13:56:43 -04:00
committed by GitHub
co-authored by Wenbo Zhu
parent 2681085624
commit bf4f34b359
4 changed files with 51 additions and 25 deletions
+20 -4
View File
@@ -800,11 +800,27 @@ export default defineCommand({
for (const f of readdirSync(destDir).filter((f) => !f.startsWith("."))) { for (const f of readdirSync(destDir).filter((f) => !f.startsWith("."))) {
console.log(` ${c.accent(f)}`); console.log(` ${c.accent(f)}`);
} }
if (!skipSkills) {
const { installAllSkills } = await import("./skills.js");
// --yes keeps it non-interactive. When Claude Code is driving
// (CLAUDECODE env var), target its native dir so skills land in
// .claude/skills/ instead of only .agents/skills/.
const args = process.env["CLAUDECODE"] ? ["--agent", "claude-code", "--yes"] : ["--yes"];
await installAllSkills({ cwd: destDir, extraArgs: args });
}
console.log(); console.log();
console.log("Get started:"); console.log("Get started:");
console.log(); console.log();
console.log(` ${c.accent("1.")} Install AI coding skills (one-time):`); if (skipSkills) {
console.log(` ${c.accent("npx skills add heygen-com/hyperframes")}`); console.log(` ${c.accent("1.")} Install AI coding skills (one-time):`);
console.log(` ${c.accent("npx skills add heygen-com/hyperframes --yes")}`);
} else {
console.log(
` ${c.accent("1.")} Restart your AI agent (new session) so it loads the skills.`,
);
}
console.log(); console.log();
console.log(` ${c.accent("2.")} Open this project with your AI coding agent:`); console.log(` ${c.accent("2.")} Open this project with your AI coding agent:`);
console.log( console.log(
@@ -1018,8 +1034,8 @@ export default defineCommand({
process.exit(0); process.exit(0);
} }
if (installSkills) { if (installSkills) {
const skillsCmd = await import("./skills.js").then((m) => m.default); const { installAllSkills } = await import("./skills.js");
await runCommand(skillsCmd, { rawArgs: [] }); await installAllSkills({ cwd: destDir });
} }
} }
+27 -17
View File
@@ -14,12 +14,16 @@ function hasNpx(): boolean {
} }
} }
function runSkillsAdd(repo: string): Promise<void> { function runSkillsAdd(
const npx = buildNpxCommand(["skills", "add", repo, "--all"]); repo: string,
opts: { cwd?: string; extraArgs?: string[] } = {},
): Promise<void> {
const npx = buildNpxCommand(["skills", "add", repo, ...(opts.extraArgs ?? ["--all"])]);
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
const child = spawn(npx.command, npx.args, { const child = spawn(npx.command, npx.args, {
stdio: "inherit", stdio: "inherit",
timeout: 120_000, timeout: 120_000,
cwd: opts.cwd,
// GH #316 — the upstream `skills` CLI shells out to `git clone`. // GH #316 — the upstream `skills` CLI shells out to `git clone`.
// When Git's clone-hook protection is active (shipped on by // When Git's clone-hook protection is active (shipped on by
// default in 2.45.1, reverted in 2.45.2, still present on many // default in 2.45.1, reverted in 2.45.2, still present on many
@@ -40,6 +44,26 @@ function runSkillsAdd(repo: string): Promise<void> {
const SOURCES = [{ name: "HyperFrames", repo: "heygen-com/hyperframes" }]; const SOURCES = [{ name: "HyperFrames", repo: "heygen-com/hyperframes" }];
export async function installAllSkills(
opts: { cwd?: string; extraArgs?: string[] } = {},
): Promise<void> {
if (!hasNpx()) {
clack.log.error(c.error("npx not found. Install Node.js and retry."));
return;
}
for (const source of SOURCES) {
console.log();
console.log(c.bold(`Installing ${source.name} skills...`));
console.log();
try {
await runSkillsAdd(source.repo, opts);
} catch {
console.log(c.dim(`${source.name} skills skipped`));
}
}
}
export default defineCommand({ export default defineCommand({
meta: { meta: {
name: "skills", name: "skills",
@@ -47,20 +71,6 @@ export default defineCommand({
}, },
args: {}, args: {},
async run() { async run() {
if (!hasNpx()) { await installAllSkills();
clack.log.error(c.error("npx not found. Install Node.js and retry."));
return;
}
for (const source of SOURCES) {
console.log();
console.log(c.bold(`Installing ${source.name} skills...`));
console.log();
try {
await runSkillsAdd(source.repo);
} catch {
console.log(c.dim(`${source.name} skills skipped`));
}
}
}, },
}); });
+2 -2
View File
@@ -21,8 +21,8 @@ The domain skills (`/hyperframes-core`, `/hyperframes-animation`, `/hyperframes-
> **Tailwind v4 projects** (`hyperframes init --tailwind`): see `/hyperframes-core` → `references/tailwind.md`. > **Tailwind v4 projects** (`hyperframes init --tailwind`): see `/hyperframes-core` → `references/tailwind.md`.
> **Skills not available?** Ask the user to run `npx hyperframes skills` and restart their > **Skills not available or need updating?** Run `npx skills add heygen-com/hyperframes`
> agent session, or install manually: `npx skills add heygen-com/hyperframes`. > and restart the agent session so the new skills load.
## Commands ## Commands
+2 -2
View File
@@ -21,8 +21,8 @@ The domain skills (`/hyperframes-core`, `/hyperframes-animation`, `/hyperframes-
> **Tailwind v4 projects** (`hyperframes init --tailwind`): see `/hyperframes-core` → `references/tailwind.md`. > **Tailwind v4 projects** (`hyperframes init --tailwind`): see `/hyperframes-core` → `references/tailwind.md`.
> **Skills not available?** Ask the user to run `npx hyperframes skills` and restart their > **Skills not available or need updating?** Run `npx skills add heygen-com/hyperframes`
> agent session, or install manually: `npx skills add heygen-com/hyperframes`. > and restart the agent session so the new skills load.
## Commands ## Commands