fix(cli): install skills into the agent's native dir #1667
Conversation
`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>` (e.g.
product-launch-video) and free-handed a composition.
Also, the default `npx skills add --all` installs to a *universal*
`.agents/skills` dir that Claude Code does not read; only an explicit
`--agent <id>` lands in the agent's native dir (`.claude/skills`).
- init: on the non-interactive branch, install skills (unless --skip-skills)
instead of only printing the command, and target the detected agent via
`resolveSkillsAgent()` (reuses `detectAgentRuntime()`).
- skills: `runSkillsAdd` accepts `{ agent }` -> `--agent <id> --yes` so skills
land in `.claude/skills`; falls back to `--all` when no agent is detected.
Verified: `hyperframes init` in a Claude Code env installs into `.claude/skills`
and `Skill(product-launch-video)` loads.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
c2f7332 to
41f5fc4
Compare
miguel-heygen
left a comment
There was a problem hiding this comment.
Tested this outside the monorepo by building the branch and running hyperframes init + hyperframes skills from a clean temp directory with CLAUDECODE=1 set. Two issues:
Bug 1: hyperframes init installs skills in the caller's CWD, not the project dir
installAllSkills() spawns npx skills add without setting cwd to the newly created project directory. Skills land in whatever directory the user ran hyperframes init from, not inside the scaffolded project.
Repro:
cd /tmp
CLAUDECODE=1 node dist/cli.js init test-project --non-interactive
ls test-project/.claude/skills/ # empty — doesn't exist
ls .claude/skills/ # 18 skills here insteadFix: Pass cwd: destDir when spawning npx skills add in runSkillsAdd, or process.chdir(destDir) before calling installAllSkills in the non-interactive init branch. The spawn option is cleaner — runSkillsAdd could accept an optional cwd.
Bug 2: hyperframes skills (standalone) doesn't target Claude Code
The standalone hyperframes skills command calls installAllSkills() with no agent arg, so it falls back to --all. With --all, skills land in .agents/skills/ only — Claude Code doesn't read that directory (as the PR description itself notes).
Repro:
cd test-project
CLAUDECODE=1 node dist/cli.js skills
ls .claude/skills/ # doesn't exist
ls .agents/skills/ # 18 skills here — invisible to Claude CodeThis is the more critical one — it's the exact path from Josh's repro. User says "update skills", Claude runs hyperframes skills, skills go to .agents/skills/, Claude can't find them.
Fix: Have the standalone command also detect the agent:
async run() {
await installAllSkills({ agent: resolveSkillsAgent() });
}What works
- Agent runtime detection (
CLAUDECODE=1→claude_code→--agent claude-code) — correct --agent claude-code --yescorrectly targets.claude/skills/— correct- Skills content is complete (18 skills, all present)
--skip-skillsflag — works
|
Superseded — took over the branch with fixes for the two bugs found during review (CWD bug + standalone skills command not detecting the agent). New PR incoming. |
…ve init
hyperframes initonly installed AI coding skills on the interactive path (behind a clack confirm). When an agent drives it non-interactively (no TTY), it just printednpx skills add ...and returned — so skills were never installed and the agent later hitUnknown skill: <workflow>(e.g. product-launch-video) and free-handed a composition.Also, the default
npx skills add --allinstalls to a universal.agents/skillsdir that Claude Code does not read; only an explicit--agent <id>lands in the agent's native dir (.claude/skills).resolveSkillsAgent()(reusesdetectAgentRuntime()).runSkillsAddaccepts{ agent }->--agent <id> --yesso skills land in.claude/skills; falls back to--allwhen no agent is detected. The explicithyperframes skillscommand is unchanged.Verified: branch
hyperframes initin a Claude Code env installs into.claude/skillsandSkill(product-launch-video)loads.What
Brief description of the change.
Why
Why is this change needed?
How
How was this implemented? Any notable design decisions?
Test plan
How was this tested?