hyperframes 0.1.6 → 0.1.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +159 -79
- package/dist/hyperframe-runtime.js +3 -3
- package/dist/hyperframe.manifest.json +1 -1
- package/dist/hyperframe.runtime.iife.js +3 -3
- package/dist/skills/captions/SKILL.md +138 -0
- package/dist/skills/compose-video/SKILL.md +149 -0
- package/dist/skills/compose-video/house-style.md +129 -0
- package/dist/skills/compose-video/palettes/bold-energetic.md +14 -0
- package/dist/skills/compose-video/palettes/clean-corporate.md +14 -0
- package/dist/skills/compose-video/palettes/dark-premium.md +14 -0
- package/dist/skills/compose-video/palettes/jewel-rich.md +14 -0
- package/dist/skills/compose-video/palettes/monochrome.md +14 -0
- package/dist/skills/compose-video/palettes/nature-earth.md +14 -0
- package/dist/skills/compose-video/palettes/neon-electric.md +14 -0
- package/dist/skills/compose-video/palettes/pastel-soft.md +14 -0
- package/dist/skills/compose-video/palettes/warm-editorial.md +14 -0
- package/dist/skills/compose-video/patterns.md +118 -0
- package/dist/templates/_shared/CLAUDE.md +50 -0
- package/package.json +7 -2
package/dist/cli.js
CHANGED
|
@@ -422,7 +422,7 @@ var VERSION;
|
|
|
422
422
|
var init_version = __esm({
|
|
423
423
|
"src/version.ts"() {
|
|
424
424
|
"use strict";
|
|
425
|
-
VERSION = true ? "0.1.
|
|
425
|
+
VERSION = true ? "0.1.7" : "0.0.0-dev";
|
|
426
426
|
}
|
|
427
427
|
});
|
|
428
428
|
|
|
@@ -2748,6 +2748,25 @@ import { existsSync as existsSync3, mkdirSync as mkdirSync3, readdirSync, rmSync
|
|
|
2748
2748
|
import { join as join3, dirname } from "path";
|
|
2749
2749
|
import { homedir as homedir3 } from "os";
|
|
2750
2750
|
import { execFileSync as execFileSync2 } from "child_process";
|
|
2751
|
+
function hasNpx() {
|
|
2752
|
+
try {
|
|
2753
|
+
execFileSync2("npx", ["--version"], { stdio: "ignore", timeout: 5e3 });
|
|
2754
|
+
return true;
|
|
2755
|
+
} catch {
|
|
2756
|
+
return false;
|
|
2757
|
+
}
|
|
2758
|
+
}
|
|
2759
|
+
function runSkillsAdd(repo, agents, global) {
|
|
2760
|
+
const args = ["skills", "add", repo, "-y"];
|
|
2761
|
+
if (global) args.push("-g");
|
|
2762
|
+
for (const agent of agents) {
|
|
2763
|
+
args.push("-a", agent);
|
|
2764
|
+
}
|
|
2765
|
+
execFileSync2("npx", args, {
|
|
2766
|
+
stdio: "ignore",
|
|
2767
|
+
timeout: 12e4
|
|
2768
|
+
});
|
|
2769
|
+
}
|
|
2751
2770
|
function hasGit2() {
|
|
2752
2771
|
try {
|
|
2753
2772
|
execFileSync2("git", ["--version"], { stdio: "ignore", timeout: 5e3 });
|
|
@@ -2764,6 +2783,7 @@ function gitClone(repo, dest) {
|
|
|
2764
2783
|
});
|
|
2765
2784
|
}
|
|
2766
2785
|
function fetchRepo(source) {
|
|
2786
|
+
const gitUrl = `https://github.com/${source.repo}.git`;
|
|
2767
2787
|
if (existsSync3(source.cache)) {
|
|
2768
2788
|
try {
|
|
2769
2789
|
execFileSync2("git", ["pull", "--ff-only"], {
|
|
@@ -2773,18 +2793,17 @@ function fetchRepo(source) {
|
|
|
2773
2793
|
env: GIT_ENV
|
|
2774
2794
|
});
|
|
2775
2795
|
} catch {
|
|
2776
|
-
const
|
|
2777
|
-
if (existsSync3(
|
|
2778
|
-
return skillsDir;
|
|
2779
|
-
}
|
|
2796
|
+
const skillsDir2 = join3(source.cache, source.skillsPath);
|
|
2797
|
+
if (existsSync3(skillsDir2)) return skillsDir2;
|
|
2780
2798
|
rmSync2(source.cache, { recursive: true, force: true });
|
|
2781
|
-
gitClone(
|
|
2799
|
+
gitClone(gitUrl, source.cache);
|
|
2782
2800
|
}
|
|
2783
2801
|
} else {
|
|
2784
2802
|
mkdirSync3(dirname(source.cache), { recursive: true });
|
|
2785
|
-
gitClone(
|
|
2803
|
+
gitClone(gitUrl, source.cache);
|
|
2786
2804
|
}
|
|
2787
|
-
|
|
2805
|
+
const skillsDir = join3(source.cache, source.skillsPath);
|
|
2806
|
+
return existsSync3(skillsDir) ? skillsDir : void 0;
|
|
2788
2807
|
}
|
|
2789
2808
|
function installSkillsFromDir(sourceDir, targetDir, sourceName) {
|
|
2790
2809
|
const installed = [];
|
|
@@ -2795,24 +2814,20 @@ function installSkillsFromDir(sourceDir, targetDir, sourceName) {
|
|
|
2795
2814
|
const skillFile = join3(sourceDir, entry.name, "SKILL.md");
|
|
2796
2815
|
if (!existsSync3(skillFile)) continue;
|
|
2797
2816
|
const destDir = join3(targetDir, entry.name);
|
|
2798
|
-
|
|
2799
|
-
if (overwritten) rmSync2(destDir, { recursive: true, force: true });
|
|
2817
|
+
if (existsSync3(destDir)) rmSync2(destDir, { recursive: true, force: true });
|
|
2800
2818
|
mkdirSync3(destDir, { recursive: true });
|
|
2801
2819
|
cpSync(join3(sourceDir, entry.name), destDir, { recursive: true });
|
|
2802
|
-
installed.push({ name: entry.name, source: sourceName
|
|
2820
|
+
installed.push({ name: entry.name, source: sourceName });
|
|
2803
2821
|
}
|
|
2804
2822
|
return installed;
|
|
2805
2823
|
}
|
|
2806
|
-
|
|
2807
|
-
if (!hasGit2()) return { count: 0, targets: [], skipped: SOURCES.map((s) => s.name) };
|
|
2808
|
-
const targets = targetNames ? TARGETS.filter((t2) => targetNames.includes(t2.flag)) : TARGETS.filter((t2) => t2.defaultEnabled);
|
|
2809
|
-
let totalCount = 0;
|
|
2824
|
+
function fallbackInstall(targets) {
|
|
2810
2825
|
const skipped = [];
|
|
2811
2826
|
const fetched = [];
|
|
2812
2827
|
for (const source of SOURCES) {
|
|
2813
2828
|
try {
|
|
2814
2829
|
const skillsDir = fetchRepo(source);
|
|
2815
|
-
if (
|
|
2830
|
+
if (skillsDir) {
|
|
2816
2831
|
fetched.push({ source, skillsDir });
|
|
2817
2832
|
} else {
|
|
2818
2833
|
skipped.push(source.name);
|
|
@@ -2821,21 +2836,45 @@ async function installAllSkills(targetNames) {
|
|
|
2821
2836
|
skipped.push(source.name);
|
|
2822
2837
|
}
|
|
2823
2838
|
}
|
|
2824
|
-
const [
|
|
2825
|
-
|
|
2826
|
-
|
|
2839
|
+
const [first, ...rest] = targets;
|
|
2840
|
+
const allInstalled = [];
|
|
2841
|
+
if (first) {
|
|
2842
|
+
mkdirSync3(first.dir, { recursive: true });
|
|
2827
2843
|
for (const { skillsDir, source } of fetched) {
|
|
2828
|
-
|
|
2829
|
-
totalCount += skills.length;
|
|
2844
|
+
allInstalled.push(...installSkillsFromDir(skillsDir, first.dir, source.name));
|
|
2830
2845
|
}
|
|
2831
2846
|
}
|
|
2832
|
-
for (const target of
|
|
2847
|
+
for (const target of rest) {
|
|
2833
2848
|
mkdirSync3(target.dir, { recursive: true });
|
|
2834
2849
|
for (const { skillsDir, source } of fetched) {
|
|
2835
2850
|
installSkillsFromDir(skillsDir, target.dir, source.name);
|
|
2836
2851
|
}
|
|
2837
2852
|
}
|
|
2838
|
-
return { count:
|
|
2853
|
+
return { count: allInstalled.length, installed: allInstalled, skipped };
|
|
2854
|
+
}
|
|
2855
|
+
async function installAllSkills(targetNames) {
|
|
2856
|
+
const targets = targetNames ? TARGETS.filter((t2) => targetNames.includes(t2.flag)) : TARGETS.filter((t2) => t2.defaultEnabled);
|
|
2857
|
+
const agents = targets.map((t2) => t2.skillsAgent);
|
|
2858
|
+
if (hasNpx()) {
|
|
2859
|
+
const skipped = [];
|
|
2860
|
+
let count = 0;
|
|
2861
|
+
for (const source of SOURCES) {
|
|
2862
|
+
try {
|
|
2863
|
+
runSkillsAdd(source.repo, agents, true);
|
|
2864
|
+
count += 1;
|
|
2865
|
+
} catch {
|
|
2866
|
+
skipped.push(source.name);
|
|
2867
|
+
}
|
|
2868
|
+
}
|
|
2869
|
+
if (count > 0) {
|
|
2870
|
+
return { count, targets: targets.map((t2) => t2.name), skipped };
|
|
2871
|
+
}
|
|
2872
|
+
}
|
|
2873
|
+
if (!hasGit2()) {
|
|
2874
|
+
return { count: 0, targets: [], skipped: SOURCES.map((s) => s.name) };
|
|
2875
|
+
}
|
|
2876
|
+
const result = fallbackInstall(targets);
|
|
2877
|
+
return { count: result.count, targets: targets.map((t2) => t2.name), skipped: result.skipped };
|
|
2839
2878
|
}
|
|
2840
2879
|
function resolveTargets(args) {
|
|
2841
2880
|
const hasAnyFlag = TARGETS.some((t2) => args[t2.flag] === true);
|
|
@@ -2846,70 +2885,57 @@ function resolveTargets(args) {
|
|
|
2846
2885
|
}
|
|
2847
2886
|
async function runInstall({ args }) {
|
|
2848
2887
|
Wt2(c.bold("hyperframes skills"));
|
|
2849
|
-
if (!hasGit2()) {
|
|
2850
|
-
R2.error(c.error("git is required to install skills. Install git and retry."));
|
|
2851
|
-
Gt(c.warn("No skills installed."));
|
|
2852
|
-
return;
|
|
2853
|
-
}
|
|
2854
2888
|
const targets = resolveTargets(args);
|
|
2855
|
-
const
|
|
2856
|
-
|
|
2857
|
-
const
|
|
2858
|
-
|
|
2859
|
-
|
|
2860
|
-
const
|
|
2861
|
-
|
|
2862
|
-
|
|
2863
|
-
|
|
2864
|
-
|
|
2865
|
-
spinner.stop(c.
|
|
2889
|
+
const agents = targets.map((t2) => t2.skillsAgent);
|
|
2890
|
+
if (hasNpx()) {
|
|
2891
|
+
const installed = [];
|
|
2892
|
+
const skippedSources = [];
|
|
2893
|
+
for (const source of SOURCES) {
|
|
2894
|
+
const spinner = be();
|
|
2895
|
+
spinner.start(`Installing ${source.name} skills...`);
|
|
2896
|
+
try {
|
|
2897
|
+
runSkillsAdd(source.repo, agents, true);
|
|
2898
|
+
installed.push(source.name);
|
|
2899
|
+
spinner.stop(c.success(`${source.name} skills installed`));
|
|
2900
|
+
} catch {
|
|
2901
|
+
skippedSources.push(source.name);
|
|
2902
|
+
spinner.stop(c.dim(`${source.name} skills skipped (unavailable)`));
|
|
2866
2903
|
}
|
|
2867
|
-
} catch {
|
|
2868
|
-
spinner.stop(c.dim(`${source.name} skills skipped (repo not accessible)`));
|
|
2869
2904
|
}
|
|
2870
|
-
|
|
2871
|
-
|
|
2872
|
-
|
|
2873
|
-
|
|
2874
|
-
const spinner = be();
|
|
2875
|
-
spinner.start(`Installing to ${target.name}...`);
|
|
2876
|
-
mkdirSync3(target.dir, { recursive: true });
|
|
2877
|
-
let count = 0;
|
|
2878
|
-
for (const { source, skillsDir } of fetched) {
|
|
2879
|
-
const skills = installSkillsFromDir(skillsDir, target.dir, source.name);
|
|
2880
|
-
count += skills.length;
|
|
2881
|
-
if (!counted) allInstalled.push(...skills);
|
|
2905
|
+
console.log();
|
|
2906
|
+
console.log(` ${c.dim("Targets:")} ${targets.map((t2) => t2.name).join(", ")}`);
|
|
2907
|
+
if (skippedSources.length > 0) {
|
|
2908
|
+
console.log(` ${c.dim("Skipped:")} ${skippedSources.join(", ")}`);
|
|
2882
2909
|
}
|
|
2883
|
-
|
|
2884
|
-
|
|
2910
|
+
console.log();
|
|
2911
|
+
if (installed.length > 0) {
|
|
2912
|
+
Gt(c.success(`${installed.join(" + ")} skills installed.`));
|
|
2913
|
+
return;
|
|
2914
|
+
}
|
|
2915
|
+
R2.warn("npx skills add failed \u2014 trying fallback...");
|
|
2916
|
+
}
|
|
2917
|
+
if (!hasGit2()) {
|
|
2918
|
+
R2.error(c.error("Neither npx nor git available. Install Node.js or git and retry."));
|
|
2919
|
+
Gt(c.warn("No skills installed."));
|
|
2920
|
+
return;
|
|
2885
2921
|
}
|
|
2922
|
+
R2.info(c.dim("Using git fallback..."));
|
|
2923
|
+
const result = fallbackInstall(targets);
|
|
2886
2924
|
console.log();
|
|
2887
2925
|
for (const source of SOURCES) {
|
|
2888
|
-
const names =
|
|
2926
|
+
const names = result.installed.filter((s) => s.source === source.name).map((s) => s.name);
|
|
2889
2927
|
if (names.length > 0) {
|
|
2890
2928
|
const label2 = `${source.name}:`.padEnd(14);
|
|
2891
2929
|
console.log(` ${c.dim(label2)} ${names.map((s) => c.accent(s)).join(", ")}`);
|
|
2892
2930
|
}
|
|
2893
2931
|
}
|
|
2894
2932
|
console.log(` ${c.dim("Targets:")} ${targets.map((t2) => t2.name).join(", ")}`);
|
|
2895
|
-
|
|
2896
|
-
|
|
2897
|
-
if (skippedSources.length > 0) {
|
|
2898
|
-
console.log(
|
|
2899
|
-
` ${c.dim("Skipped:")} ${skippedSources.map((s) => s.name).join(", ")} (repo not accessible)`
|
|
2900
|
-
);
|
|
2933
|
+
if (result.skipped.length > 0) {
|
|
2934
|
+
console.log(` ${c.dim("Skipped:")} ${result.skipped.join(", ")}`);
|
|
2901
2935
|
}
|
|
2902
2936
|
console.log();
|
|
2903
|
-
if (
|
|
2904
|
-
|
|
2905
|
-
const skippedNames = skippedSources.map((s) => s.name).join(", ");
|
|
2906
|
-
Gt(
|
|
2907
|
-
c.warn(
|
|
2908
|
-
`${allInstalled.length} skills ready (${readySources}). Unavailable: ${skippedNames}.`
|
|
2909
|
-
)
|
|
2910
|
-
);
|
|
2911
|
-
} else if (allInstalled.length > 0) {
|
|
2912
|
-
Gt(c.success(`${allInstalled.length} skills ready.`));
|
|
2937
|
+
if (result.count > 0) {
|
|
2938
|
+
Gt(c.success(`${result.count} skills ready.`));
|
|
2913
2939
|
} else {
|
|
2914
2940
|
Gt(c.warn("No skills installed."));
|
|
2915
2941
|
}
|
|
@@ -2925,24 +2951,28 @@ var init_install_skills = __esm({
|
|
|
2925
2951
|
{
|
|
2926
2952
|
name: "Claude Code",
|
|
2927
2953
|
flag: "claude",
|
|
2954
|
+
skillsAgent: "claude-code",
|
|
2928
2955
|
dir: join3(homedir3(), ".claude", "skills"),
|
|
2929
2956
|
defaultEnabled: true
|
|
2930
2957
|
},
|
|
2931
2958
|
{
|
|
2932
2959
|
name: "Gemini CLI",
|
|
2933
2960
|
flag: "gemini",
|
|
2961
|
+
skillsAgent: "gemini-cli",
|
|
2934
2962
|
dir: join3(homedir3(), ".gemini", "skills"),
|
|
2935
2963
|
defaultEnabled: true
|
|
2936
2964
|
},
|
|
2937
2965
|
{
|
|
2938
2966
|
name: "Codex CLI",
|
|
2939
2967
|
flag: "codex",
|
|
2968
|
+
skillsAgent: "codex",
|
|
2940
2969
|
dir: join3(homedir3(), ".codex", "skills"),
|
|
2941
2970
|
defaultEnabled: true
|
|
2942
2971
|
},
|
|
2943
2972
|
{
|
|
2944
2973
|
name: "Cursor",
|
|
2945
2974
|
flag: "cursor",
|
|
2975
|
+
skillsAgent: "cursor",
|
|
2946
2976
|
get dir() {
|
|
2947
2977
|
return join3(process.cwd(), ".cursor", "skills");
|
|
2948
2978
|
},
|
|
@@ -2952,13 +2982,13 @@ var init_install_skills = __esm({
|
|
|
2952
2982
|
SOURCES = [
|
|
2953
2983
|
{
|
|
2954
2984
|
name: "HyperFrames",
|
|
2955
|
-
repo: "
|
|
2985
|
+
repo: "heygen-com/hyperframes",
|
|
2956
2986
|
skillsPath: "skills",
|
|
2957
2987
|
cache: join3(homedir3(), ".cache", "hyperframes", "hyperframes-skills")
|
|
2958
2988
|
},
|
|
2959
2989
|
{
|
|
2960
2990
|
name: "GSAP",
|
|
2961
|
-
repo: "
|
|
2991
|
+
repo: "greensock/gsap-skills",
|
|
2962
2992
|
skillsPath: "skills",
|
|
2963
2993
|
cache: join3(homedir3(), ".cache", "hyperframes", "gsap-skills")
|
|
2964
2994
|
}
|
|
@@ -24261,12 +24291,21 @@ function transcodeToMp4(inputPath, outputPath) {
|
|
|
24261
24291
|
child.on("error", () => resolvePromise(false));
|
|
24262
24292
|
});
|
|
24263
24293
|
}
|
|
24264
|
-
function
|
|
24265
|
-
const
|
|
24266
|
-
const devPath = resolve14(
|
|
24267
|
-
const builtPath = resolve14(
|
|
24294
|
+
function resolveAssetDir(devSegments, builtSegments) {
|
|
24295
|
+
const base = dirname13(fileURLToPath5(import.meta.url));
|
|
24296
|
+
const devPath = resolve14(base, ...devSegments);
|
|
24297
|
+
const builtPath = resolve14(base, ...builtSegments);
|
|
24268
24298
|
return existsSync26(devPath) ? devPath : builtPath;
|
|
24269
24299
|
}
|
|
24300
|
+
function getStaticTemplateDir(templateId) {
|
|
24301
|
+
return resolveAssetDir(["..", "templates", templateId], ["templates", templateId]);
|
|
24302
|
+
}
|
|
24303
|
+
function getSharedTemplateDir() {
|
|
24304
|
+
return resolveAssetDir(["..", "templates", "_shared"], ["templates", "_shared"]);
|
|
24305
|
+
}
|
|
24306
|
+
function getBundledSkillsDir() {
|
|
24307
|
+
return resolveAssetDir(["..", "..", "..", "..", "skills"], ["skills"]);
|
|
24308
|
+
}
|
|
24270
24309
|
function patchVideoSrc(dir, videoFilename, durationSeconds) {
|
|
24271
24310
|
const htmlFiles = readdirSync7(dir, { withFileTypes: true, recursive: true }).filter((e) => e.isFile() && e.name.endsWith(".html")).map((e) => join24(e.parentPath ?? e.path, e.name));
|
|
24272
24311
|
for (const file of htmlFiles) {
|
|
@@ -24417,6 +24456,28 @@ function scaffoldProject(destDir, name, templateId, localVideoName, durationSeco
|
|
|
24417
24456
|
),
|
|
24418
24457
|
"utf-8"
|
|
24419
24458
|
);
|
|
24459
|
+
const sharedDir = getSharedTemplateDir();
|
|
24460
|
+
if (existsSync26(sharedDir)) {
|
|
24461
|
+
for (const entry of readdirSync7(sharedDir, { withFileTypes: true })) {
|
|
24462
|
+
const src = join24(sharedDir, entry.name);
|
|
24463
|
+
const dest = resolve14(destDir, entry.name);
|
|
24464
|
+
if (entry.isFile() || entry.isSymbolicLink()) {
|
|
24465
|
+
copyFileSync3(src, dest);
|
|
24466
|
+
}
|
|
24467
|
+
}
|
|
24468
|
+
}
|
|
24469
|
+
const skillsSrcDir = getBundledSkillsDir();
|
|
24470
|
+
if (existsSync26(skillsSrcDir)) {
|
|
24471
|
+
const projectSkills = ["compose-video", "captions"];
|
|
24472
|
+
for (const skill of projectSkills) {
|
|
24473
|
+
const src = join24(skillsSrcDir, skill);
|
|
24474
|
+
if (existsSync26(src)) {
|
|
24475
|
+
const dest = resolve14(destDir, ".claude", "skills", skill);
|
|
24476
|
+
mkdirSync18(dest, { recursive: true });
|
|
24477
|
+
cpSync2(src, dest, { recursive: true });
|
|
24478
|
+
}
|
|
24479
|
+
}
|
|
24480
|
+
}
|
|
24420
24481
|
}
|
|
24421
24482
|
async function nextStepLoop(destDir) {
|
|
24422
24483
|
while (true) {
|
|
@@ -24571,9 +24632,28 @@ Example: hyperframes init my-video --template blank --video video.mp4`);
|
|
|
24571
24632
|
await installSkills(false);
|
|
24572
24633
|
}
|
|
24573
24634
|
console.log(c.success(`Created ${c.accent(name2 + "/")}`));
|
|
24574
|
-
for (const f of readdirSync7(destDir2)) {
|
|
24635
|
+
for (const f of readdirSync7(destDir2).filter((f2) => !f2.startsWith("."))) {
|
|
24575
24636
|
console.log(` ${c.accent(f)}`);
|
|
24576
24637
|
}
|
|
24638
|
+
console.log();
|
|
24639
|
+
console.log("Next steps:");
|
|
24640
|
+
console.log(
|
|
24641
|
+
` ${c.accent(`cd ${name2}`)} && ${c.accent("npx hyperframes dev")} ${c.dim("# preview in studio")}`
|
|
24642
|
+
);
|
|
24643
|
+
console.log(
|
|
24644
|
+
` ${c.accent(`cd ${name2}`)} && ${c.accent("npx hyperframes render")} ${c.dim("# render to MP4")}`
|
|
24645
|
+
);
|
|
24646
|
+
console.log(
|
|
24647
|
+
` ${c.accent("npx hyperframes docs")} ${c.dim("<topic>")} ${c.dim("# learn composition syntax")}`
|
|
24648
|
+
);
|
|
24649
|
+
console.log(
|
|
24650
|
+
` ${c.dim("topics: data-attributes, gsap, compositions, rendering, templates, troubleshooting")}`
|
|
24651
|
+
);
|
|
24652
|
+
console.log();
|
|
24653
|
+
console.log(
|
|
24654
|
+
` ${c.dim("AI skills installed \u2014 open this folder in your AI coding agent to get started.")}`
|
|
24655
|
+
);
|
|
24656
|
+
console.log(` ${c.dim("Full docs: hyperframes.heygen.com")}`);
|
|
24577
24657
|
return;
|
|
24578
24658
|
}
|
|
24579
24659
|
Wt2("Create a new HyperFrames project");
|