diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2ba539c1d9..58ba66aa04 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -227,8 +227,7 @@ jobs: - uses: ./.github/actions/prepare-ffmpeg-bin - run: bun install --frozen-lockfile - run: bun run test:scripts - - run: bun run --filter '@hyperframes/parsers' build - - run: bun run --filter '@hyperframes/studio-server' build + - run: bun run --filter '@hyperframes/{parsers,lint,studio-server}' build - run: bun run --cwd packages/core build - run: bun run --cwd packages/core build:hyperframes-runtime - run: bun run --filter '!@hyperframes/producer' test @@ -361,8 +360,7 @@ jobs: # Build workspace deps so the studio vite.config.ts (loaded by Node) can # resolve @hyperframes/core and @hyperframes/studio-server via the "node" # export condition (dist). - - run: bun run --filter '@hyperframes/parsers' build - - run: bun run --filter '@hyperframes/studio-server' build + - run: bun run --filter '@hyperframes/{parsers,lint,studio-server}' build - run: bun run --cwd packages/core build - run: bun run --cwd packages/core build:hyperframes-runtime - name: Start studio and check for runtime errors @@ -575,6 +573,10 @@ jobs: test -s /tmp/hf-cli-input.mp4 - name: Smoke-test CLI from monorepo source + # init's --skip-skills flag is neutered (see init.ts); opt out of the + # GitHub skills check via this env so the smoke test stays offline/fast. + env: + HYPERFRAMES_SKIP_SKILLS: "1" run: | set -euo pipefail rm -rf /tmp/hf-cli-inside @@ -628,6 +630,10 @@ jobs: npm install -g --prefix /tmp/hf-cli-global "$HF_CLI_TARBALL" - name: Smoke-test packed CLI outside monorepo + # init's --skip-skills flag is neutered (see init.ts); opt out of the + # GitHub skills check via this env so the smoke test stays offline/fast. + env: + HYPERFRAMES_SKIP_SKILLS: "1" run: | set -euo pipefail export PATH="/tmp/hf-cli-global/bin:$PATH" diff --git a/.github/workflows/windows-render.yml b/.github/workflows/windows-render.yml index e8d9f5b63a..5bff10743a 100644 --- a/.github/workflows/windows-render.yml +++ b/.github/workflows/windows-render.yml @@ -199,6 +199,10 @@ jobs: - name: Scaffold canary composition shell: pwsh + # init's --skip-skills flag is neutered (see init.ts); opt out of the + # GitHub skills check via this env so the canary scaffold stays offline. + env: + HYPERFRAMES_SKIP_SKILLS: "1" run: | New-Item -ItemType Directory -Force -Path "$env:RUNNER_TEMP\windows-canary" | Out-Null cd "$env:RUNNER_TEMP\windows-canary" diff --git a/packages/cli/src/commands/init.test.ts b/packages/cli/src/commands/init.test.ts index 6334ea1740..e913d61191 100644 --- a/packages/cli/src/commands/init.test.ts +++ b/packages/cli/src/commands/init.test.ts @@ -18,6 +18,9 @@ function runInit(args: string[]): { status: number; stdout: string; stderr: stri const res = spawnSync("bun", ["run", cliEntry, "init", ...args], { encoding: "utf-8", timeout: 30_000, + // The `--skip-skills` flag is neutered (see init.ts); the GitHub skills check + // is opted out only via this env var, so tests stay offline and fast. + env: { ...process.env, HYPERFRAMES_SKIP_SKILLS: "1" }, }); return { status: res.status ?? -1, diff --git a/packages/cli/src/commands/init.ts b/packages/cli/src/commands/init.ts index 03b611974d..a921c002bf 100644 --- a/packages/cli/src/commands/init.ts +++ b/packages/cli/src/commands/init.ts @@ -10,7 +10,10 @@ export const examples: Example[] = [ ["Start from an audio file", "hyperframes init my-video --audio track.mp3"], ["Scaffold with Tailwind CSS", "hyperframes init my-video --example blank --tailwind"], ["Non-interactive mode (for CI or AI agents)", "hyperframes init my-video --non-interactive"], - ["Skip AI coding skills installation", "hyperframes init my-video --skip-skills"], + [ + "Opt out of the GitHub skills check (CI/tests only)", + "HYPERFRAMES_SKIP_SKILLS=1 hyperframes init my-video --non-interactive", + ], ]; import { existsSync, @@ -601,7 +604,19 @@ async function ensureSkillsCurrent(destDir: string): Promise { // installAllSkills installs the full set once globally and mirrors it into // every installed agent's global dir — project-independent, so a freshly // scaffolded project doesn't need any agent folders yet. - await installAllSkills({ cwd: destDir }); + // + // Best-effort: installAllSkills (non-strict here) already swallows its own + // failures, but now that --skip-skills no longer escapes this path every + // init runs it — including offline ones, where checkSkills throws and we + // fall through to "install anyway". Wrap defensively so a skills-install + // failure can never break `init` itself; it only warns and proceeds. + try { + await installAllSkills({ cwd: destDir }); + } catch (err) { + console.log( + c.dim(`AI coding skills install skipped: ${err instanceof Error ? err.message : err}`), + ); + } } else { console.log(c.success("AI coding skills are already up to date.")); } @@ -670,7 +685,8 @@ export default defineCommand({ }, "skip-skills": { type: "boolean", - description: "Skip AI coding skills installation", + description: + "[temporarily ignored] init always checks AI skills against GitHub while the skills.sh registry catches up; set HYPERFRAMES_SKIP_SKILLS=1 to opt out (CI/tests)", }, tailwind: { type: "boolean", @@ -705,13 +721,32 @@ export default defineCommand({ const videoFlag = args.video; const audioFlag = args.audio; const skipTranscribe = args["skip-transcribe"] === true; - const skipSkills = args["skip-skills"] === true; + // Temporary measure while the skills.sh registry sync lags GitHub main: the + // `--skip-skills` FLAG is neutered so an agent (or user) that passes it can + // NOT dodge the GitHub skills freshness check. The "don't pass --skip-skills" + // guidance lives in SKILL.md, which ships through the same laggy skills.sh + // channel and can't be relied on to reach the agent — so the guarantee has to + // live in the CLI, the one channel that updates promptly (`npx + // hyperframes@latest`). CI and unit tests still opt out via the + // HYPERFRAMES_SKIP_SKILLS=1 env var, which the agent/user CLI path never sets. + // Revert to `args["skip-skills"] === true` once skills.sh catches up. + const skipSkills = process.env.HYPERFRAMES_SKIP_SKILLS === "1"; + const skipSkillsFlagIgnored = args["skip-skills"] === true && !skipSkills; const tailwind = args.tailwind === true; const nonInteractive = args["non-interactive"] === true; const modelFlag = args.model; const languageFlag = args.language; const interactive = !nonInteractive && process.stdout.isTTY === true; + if (skipSkillsFlagIgnored) { + console.log( + c.dim( + "Note: --skip-skills is temporarily ignored — init always checks AI skills " + + "against GitHub while the skills.sh registry catches up.", + ), + ); + } + let resolutionPreset: CanvasResolution | undefined; if (args.resolution !== undefined) { resolutionPreset = normalizeResolutionFlag(args.resolution); @@ -1053,7 +1088,8 @@ export default defineCommand({ clack.note(files.map((f) => c.accent(f)).join("\n"), c.success(`Created ${name}/`)); // Check skills against GitHub and (re)install only if outdated or missing — - // init is the one place the full set is pulled. Opt out with --skip-skills. + // init is the one place the full set is pulled. The --skip-skills flag is + // temporarily neutered (see above); CI/tests opt out via HYPERFRAMES_SKIP_SKILLS=1. if (!skipSkills) { await ensureSkillsCurrent(destDir); } diff --git a/skills-manifest.json b/skills-manifest.json index 8296669ac4..165fa14ff2 100644 --- a/skills-manifest.json +++ b/skills-manifest.json @@ -14,7 +14,7 @@ "files": 1 }, "hyperframes": { - "hash": "1b35d1424ca18261", + "hash": "55f1e72887f8f983", "files": 1 }, "hyperframes-animation": { @@ -22,7 +22,7 @@ "files": 115 }, "hyperframes-cli": { - "hash": "4eda382550997fe8", + "hash": "e493e8902805efef", "files": 7 }, "hyperframes-core": { diff --git a/skills/hyperframes-cli/SKILL.md b/skills/hyperframes-cli/SKILL.md index f893d9fd56..026d56c2cc 100644 --- a/skills/hyperframes-cli/SKILL.md +++ b/skills/hyperframes-cli/SKILL.md @@ -9,7 +9,7 @@ Everything runs through `npx hyperframes` unless project instructions specify a ## Workflow -1. **Scaffold** — `npx hyperframes init my-video` (or `capture` from a URL). `init` also checks the installed skills against the latest on GitHub and updates the global set if any are out of date — keep it on (don't pass `--skip-skills`) so each new project pulls our latest skills. +1. **Scaffold** — `npx hyperframes init my-video` (or `capture` from a URL). `init` also checks the installed skills against the latest on GitHub and updates the global set if any are out of date. The `--skip-skills` flag is currently neutered (temporary, while the skills.sh registry catches up), so every `init` runs this check and pulls our latest skills regardless. 2. **Write** — author HTML composition (see the `hyperframes-core` skill) 3. **Lint** — `npx hyperframes lint` 4. **Validate** — `npx hyperframes validate` (runtime errors + contrast) diff --git a/skills/hyperframes-cli/references/init-and-scaffold.md b/skills/hyperframes-cli/references/init-and-scaffold.md index 85fc11ef46..6c319f1cf2 100644 --- a/skills/hyperframes-cli/references/init-and-scaffold.md +++ b/skills/hyperframes-cli/references/init-and-scaffold.md @@ -21,7 +21,7 @@ Templates: `blank`, `warm-grain`, `play-mode`, `swiss-grid`, `vignelli`, `decisi Other useful flags: - `--resolution` — preset: `landscape` (1920×1080), `portrait` (1080×1920), `landscape-4k`, `portrait-4k`, `square` (1080×1080), `square-4k`. Aliases: `1080p`, `4k`, `uhd`, `1080p-square`, `4k-square`. -- `--skip-skills` — don't install AI coding skills after scaffold. +- `--skip-skills` — **temporarily ignored**: `init` always checks AI coding skills against GitHub while the skills.sh registry catches up. To opt out (CI/tests), set the `HYPERFRAMES_SKIP_SKILLS=1` env var instead. - `--skip-transcribe` — don't auto-transcribe `--audio` / `--video` with Whisper. - `--model`, `--language` — Whisper model / language for the auto-transcription. diff --git a/skills/hyperframes/SKILL.md b/skills/hyperframes/SKILL.md index 3845b785c1..f446e30f97 100644 --- a/skills/hyperframes/SKILL.md +++ b/skills/hyperframes/SKILL.md @@ -85,7 +85,7 @@ After they run it, re-read the workflow's skill and continue. ## Keeping skills current -HyperFrames skills are versioned. `npx hyperframes init` checks the installed skills against the latest on GitHub and installs/refreshes the **full** set whenever anything is out of date or missing — so a freshly init'd project always has the complete, latest set (and re-running init on an up-to-date project is a no-op). The check is a quick GitHub round-trip; offline (or rate-limited) it falls back to installing after a short timeout, so init never hard-fails on a network hiccup. The creation workflows scaffold with `init` (no `--skip-skills`), so starting a new project always runs this check and pulls our latest skills from GitHub when they're stale. Opt out only by adding `--skip-skills`. +HyperFrames skills are versioned. `npx hyperframes init` checks the installed skills against the latest on GitHub and installs/refreshes the **full** set whenever anything is out of date or missing — so a freshly init'd project always has the complete, latest set (and re-running init on an up-to-date project is a no-op). The check is a quick GitHub round-trip; offline (or rate-limited) it falls back to installing after a short timeout, so init never hard-fails on a network hiccup. The creation workflows scaffold with `init`, so starting a new project always runs this check and pulls our latest skills from GitHub when they're stale. The `--skip-skills` flag is currently neutered (a temporary measure while the skills.sh registry catches up): passing it no longer skips the check, so every `init` checks GitHub. CI/tests opt out via the `HYPERFRAMES_SKIP_SKILLS=1` env var. If a task is behaving unexpectedly, or before a long build, confirm the installed skills are current: