hyper-animator-codex 0.6.0 → 0.7.1
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/README.md +53 -7
- package/bin/hyper-animator-codex.mjs +30 -8
- package/bin/postinstall.mjs +19 -0
- package/lib/install-options.mjs +3 -0
- package/lib/install-skill.mjs +84 -2
- package/package.json +3 -2
- package/skills/hyper-animator-codex/SKILL.md +23 -18
- package/skills/hyper-animator-codex/references/narration-audio-workflow.md +110 -0
- package/skills/hyper-animator-codex/scripts/detect_project_files.mjs +178 -0
- package/skills/hyper-animator-codex/scripts/generate_minimax_tts.mjs +556 -0
- package/skills/hyper-animator-codex/scripts/generate_subtitles.mjs +181 -0
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
Install the `hyper-animator-codex` Codex skill from npm.
|
|
4
4
|
|
|
5
|
-
The skill guides Codex through a HyperFrames animation workflow: natural-language brief, clarification questions, catalog-map intent matching, style and motion selection, HTML animation authoring, validation, user approval, and render handoff.
|
|
5
|
+
The skill guides Codex through a HyperFrames animation workflow: natural-language brief, outline/narration detection, clarification questions, catalog-map intent matching, style and motion selection, HTML animation authoring, validation, user approval, and render handoff.
|
|
6
6
|
|
|
7
7
|
## Install
|
|
8
8
|
|
|
@@ -22,19 +22,31 @@ Or install the CLI globally:
|
|
|
22
22
|
|
|
23
23
|
```bash
|
|
24
24
|
npm install -g hyper-animator-codex
|
|
25
|
-
hyper-animator-codex install --force
|
|
26
25
|
```
|
|
27
26
|
|
|
28
|
-
|
|
27
|
+
Global install runs a postinstall step that copies the skill to both Codex and Claude Code:
|
|
29
28
|
|
|
30
29
|
```text
|
|
31
30
|
${CODEX_HOME:-$HOME/.codex}/skills/hyper-animator-codex
|
|
31
|
+
${CLAUDE_HOME:-$HOME/.claude}/skills/hyper-animator-codex
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
To skip automatic skill installation during npm install:
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
HYPER_ANIMATOR_CODEX_SKIP_POSTINSTALL=1 npm install -g hyper-animator-codex
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
You can also run or re-run installation manually:
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
hyper-animator-codex install --force
|
|
32
44
|
```
|
|
33
45
|
|
|
34
|
-
Use
|
|
46
|
+
Use one custom skills directory:
|
|
35
47
|
|
|
36
48
|
```bash
|
|
37
|
-
npx hyper-animator-codex install --target /path/to/
|
|
49
|
+
npx hyper-animator-codex install --target /path/to/skills
|
|
38
50
|
```
|
|
39
51
|
|
|
40
52
|
## Git Checkpoints
|
|
@@ -52,9 +64,9 @@ node skills/hyper-animator-codex/scripts/git_checkpoint.mjs \
|
|
|
52
64
|
|
|
53
65
|
Existing Git repositories with uncommitted changes are protected: the helper stops instead of mixing user edits into automatic commits. Large video and audio files above 10 MB are skipped by default and recorded in a manifest under `hyper-animator-output/git-checkpoints/`.
|
|
54
66
|
|
|
55
|
-
## MiniMax
|
|
67
|
+
## MiniMax Audio Configuration
|
|
56
68
|
|
|
57
|
-
MiniMax is the preferred generated-background-music provider. Configure it during install so the copied Codex skill can generate music without asking for credentials later:
|
|
69
|
+
MiniMax is the preferred generated-background-music provider and the required narration TTS provider. Configure it during install so the copied Codex skill can generate music and voiceover without asking for credentials later:
|
|
58
70
|
|
|
59
71
|
```bash
|
|
60
72
|
npx hyper-animator-codex install --force \
|
|
@@ -104,10 +116,44 @@ When rendering video, hide preview controls with any one of:
|
|
|
104
116
|
<html data-render-mode="video">
|
|
105
117
|
```
|
|
106
118
|
|
|
119
|
+
## Narration And Subtitles
|
|
120
|
+
|
|
121
|
+
Detect outline and narration files in a project directory:
|
|
122
|
+
|
|
123
|
+
```bash
|
|
124
|
+
node skills/hyper-animator-codex/scripts/detect_project_files.mjs --dir . --pretty
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
List MiniMax voices, cloned voices first:
|
|
128
|
+
|
|
129
|
+
```bash
|
|
130
|
+
node skills/hyper-animator-codex/scripts/generate_minimax_tts.mjs --list-voices --voice-type all
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
Generate narration audio from `narration.json`:
|
|
134
|
+
|
|
135
|
+
```bash
|
|
136
|
+
node skills/hyper-animator-codex/scripts/generate_minimax_tts.mjs \
|
|
137
|
+
--narration-json narration.json \
|
|
138
|
+
--output-dir hyper-animator-output/voice
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
Generate timed subtitle JSON and SRT:
|
|
142
|
+
|
|
143
|
+
```bash
|
|
144
|
+
node skills/hyper-animator-codex/scripts/generate_subtitles.mjs \
|
|
145
|
+
--narration narration.json \
|
|
146
|
+
--output-dir hyper-animator-output/subtitles \
|
|
147
|
+
--style clean
|
|
148
|
+
```
|
|
149
|
+
|
|
107
150
|
## Contents
|
|
108
151
|
|
|
109
152
|
- `skills/hyper-animator-codex/SKILL.md`: Codex skill instructions.
|
|
110
153
|
- `skills/hyper-animator-codex/references/`: HyperFrames catalog map, workflow guide, pseudocode, and request examples.
|
|
154
|
+
- `skills/hyper-animator-codex/scripts/detect_project_files.mjs`: top-level outline and narration detector for first-run/restart workflows.
|
|
155
|
+
- `skills/hyper-animator-codex/scripts/generate_minimax_tts.mjs`: MiniMax voice listing and narration TTS helper.
|
|
156
|
+
- `skills/hyper-animator-codex/scripts/generate_subtitles.mjs`: timed subtitle JSON/SRT generator.
|
|
111
157
|
- `skills/hyper-animator-codex/scripts/git_checkpoint.mjs`: Git initialization and stage-commit helper for `/hyper-animator` runs.
|
|
112
158
|
- `skills/hyper-animator-codex/scripts/validate_hyperframes_html.py`: static pre-render HTML quality gate.
|
|
113
159
|
|
|
@@ -1,21 +1,29 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
installSkillToTargets,
|
|
4
|
+
resolveClaudeCodeSkillsRoot,
|
|
5
|
+
resolveCodexSkillsRoot,
|
|
6
|
+
SKILL_NAME,
|
|
7
|
+
} from "../lib/install-skill.mjs";
|
|
3
8
|
import { parseInstallArgs } from "../lib/install-options.mjs";
|
|
4
9
|
|
|
5
10
|
function printHelp() {
|
|
6
11
|
console.log(`Usage:
|
|
7
12
|
hyper-animator-codex install [--force] [--target <skills-dir>] [MiniMax options]
|
|
8
13
|
hyper-animator-codex path
|
|
14
|
+
hyper-animator-codex paths
|
|
9
15
|
hyper-animator-codex help
|
|
10
16
|
|
|
11
17
|
Commands:
|
|
12
|
-
install Install the packaged ${SKILL_NAME} skill into Codex
|
|
18
|
+
install Install the packaged ${SKILL_NAME} skill into Codex and Claude Code
|
|
13
19
|
path Print the default Codex skills directory
|
|
20
|
+
paths Print default Codex and Claude Code skills directories
|
|
14
21
|
help Show this help
|
|
15
22
|
|
|
16
23
|
Options:
|
|
17
24
|
--force Replace an existing installed skill
|
|
18
|
-
--
|
|
25
|
+
--quiet Suppress successful install output
|
|
26
|
+
--target <dir> Install into one specific skills directory
|
|
19
27
|
--minimax-api-key <key> Save MiniMax API key into installed skill config
|
|
20
28
|
--minimax-group-id <group_id> Save MiniMax group_id into installed skill config
|
|
21
29
|
--minimax-model <model> MiniMax text music model: music-2.6 or music-2.6-free
|
|
@@ -39,20 +47,34 @@ async function main() {
|
|
|
39
47
|
return;
|
|
40
48
|
}
|
|
41
49
|
|
|
50
|
+
if (command === "paths") {
|
|
51
|
+
console.log(`Codex: ${resolveCodexSkillsRoot()}`);
|
|
52
|
+
console.log(`Claude Code: ${resolveClaudeCodeSkillsRoot()}`);
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
|
|
42
56
|
if (command !== "install") {
|
|
43
57
|
throw new Error(`Unknown command: ${command}`);
|
|
44
58
|
}
|
|
45
59
|
|
|
46
60
|
const options = parseInstallArgs(args);
|
|
47
|
-
const result = await
|
|
61
|
+
const result = await installSkillToTargets(options);
|
|
62
|
+
|
|
63
|
+
if (options.quiet) {
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
48
66
|
|
|
49
67
|
console.log(`Installed ${result.skillName}`);
|
|
50
68
|
console.log(`Source: ${result.sourcePath}`);
|
|
51
|
-
console.log(`Target: ${result.installedPath}`);
|
|
52
69
|
|
|
53
|
-
|
|
54
|
-
console.log(
|
|
55
|
-
|
|
70
|
+
for (const install of result.installs) {
|
|
71
|
+
console.log(`${install.tool}: ${install.installedPath}`);
|
|
72
|
+
if (install.minimaxConfigPath) {
|
|
73
|
+
console.log(`${install.tool} MiniMax config: ${install.minimaxConfigPath}`);
|
|
74
|
+
if (install.minimaxConfig) {
|
|
75
|
+
console.log(`${install.tool} MiniMax model: ${install.minimaxConfig.model}`);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
56
78
|
}
|
|
57
79
|
}
|
|
58
80
|
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { installSkillToTargets } from "../lib/install-skill.mjs";
|
|
3
|
+
|
|
4
|
+
if (process.env.HYPER_ANIMATOR_CODEX_SKIP_POSTINSTALL === "1") {
|
|
5
|
+
process.exit(0);
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
try {
|
|
9
|
+
const result = await installSkillToTargets({
|
|
10
|
+
force: true,
|
|
11
|
+
quiet: true,
|
|
12
|
+
env: process.env,
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
const targets = result.installs.map((install) => `${install.tool}:${install.installedPath}`).join(", ");
|
|
16
|
+
console.log(`hyper-animator-codex installed skills: ${targets}`);
|
|
17
|
+
} catch (error) {
|
|
18
|
+
console.warn(`hyper-animator-codex postinstall skipped: ${error.message}`);
|
|
19
|
+
}
|
package/lib/install-options.mjs
CHANGED
|
@@ -11,6 +11,7 @@ function requireValue(args, index, flag) {
|
|
|
11
11
|
export function parseInstallArgs(args) {
|
|
12
12
|
const parsed = {
|
|
13
13
|
force: false,
|
|
14
|
+
quiet: false,
|
|
14
15
|
targetRoot: undefined,
|
|
15
16
|
minimaxConfig: {},
|
|
16
17
|
};
|
|
@@ -20,6 +21,8 @@ export function parseInstallArgs(args) {
|
|
|
20
21
|
|
|
21
22
|
if (arg === "--force") {
|
|
22
23
|
parsed.force = true;
|
|
24
|
+
} else if (arg === "--quiet") {
|
|
25
|
+
parsed.quiet = true;
|
|
23
26
|
} else if (arg === "--target") {
|
|
24
27
|
parsed.targetRoot = requireValue(args, index, arg);
|
|
25
28
|
index += 1;
|
package/lib/install-skill.mjs
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import { cp, mkdir, rm, stat } from "node:fs/promises";
|
|
1
|
+
import { chmod, cp, mkdir, readFile, rm, stat, writeFile } from "node:fs/promises";
|
|
2
2
|
import { homedir } from "node:os";
|
|
3
3
|
import { basename, dirname, join } from "node:path";
|
|
4
4
|
import { fileURLToPath } from "node:url";
|
|
5
5
|
|
|
6
6
|
import {
|
|
7
|
+
MINIMAX_CONFIG_RELATIVE_PATH,
|
|
7
8
|
redactMinimaxConfig,
|
|
8
9
|
resolveInstallMinimaxConfig,
|
|
9
10
|
writeMinimaxConfig,
|
|
@@ -43,6 +44,44 @@ export function resolveCodexSkillsRoot(env = process.env) {
|
|
|
43
44
|
return join(home, ".codex", "skills");
|
|
44
45
|
}
|
|
45
46
|
|
|
47
|
+
export function resolveClaudeCodeSkillsRoot(env = process.env) {
|
|
48
|
+
if (env.CLAUDE_HOME) {
|
|
49
|
+
return join(env.CLAUDE_HOME, "skills");
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
const home = env.HOME || homedir();
|
|
53
|
+
if (!home) {
|
|
54
|
+
throw new Error("Cannot resolve Claude Code skills directory: HOME is not set");
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
return join(home, ".claude", "skills");
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
async function readExistingMinimaxConfig(installedPath) {
|
|
61
|
+
const configPath = join(installedPath, MINIMAX_CONFIG_RELATIVE_PATH);
|
|
62
|
+
|
|
63
|
+
if (!(await pathExists(configPath))) {
|
|
64
|
+
return null;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
return {
|
|
68
|
+
configPath,
|
|
69
|
+
body: await readFile(configPath, "utf8"),
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
async function restoreExistingMinimaxConfig(installedPath, existingConfig) {
|
|
74
|
+
if (!existingConfig) {
|
|
75
|
+
return null;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
const configPath = join(installedPath, MINIMAX_CONFIG_RELATIVE_PATH);
|
|
79
|
+
await mkdir(dirname(configPath), { recursive: true });
|
|
80
|
+
await writeFile(configPath, existingConfig.body, { encoding: "utf8", mode: 0o600 });
|
|
81
|
+
await chmod(configPath, 0o600);
|
|
82
|
+
return configPath;
|
|
83
|
+
}
|
|
84
|
+
|
|
46
85
|
export async function installSkill(options = {}) {
|
|
47
86
|
const targetRoot = options.targetRoot || resolveCodexSkillsRoot(options.env);
|
|
48
87
|
const sourcePath = options.sourcePath || join(packageRoot, "skills", SKILL_NAME);
|
|
@@ -55,6 +94,8 @@ export async function installSkill(options = {}) {
|
|
|
55
94
|
|
|
56
95
|
await mkdir(targetRoot, { recursive: true });
|
|
57
96
|
|
|
97
|
+
const existingMinimaxConfig = force ? await readExistingMinimaxConfig(installedPath) : null;
|
|
98
|
+
|
|
58
99
|
if (await pathExists(installedPath)) {
|
|
59
100
|
if (!force) {
|
|
60
101
|
throw new Error(`${SKILL_NAME} already exists at ${installedPath}; rerun with --force to replace it`);
|
|
@@ -74,12 +115,53 @@ export async function installSkill(options = {}) {
|
|
|
74
115
|
const minimaxWrite = resolvedMinimaxConfig
|
|
75
116
|
? await writeMinimaxConfig(installedPath, resolvedMinimaxConfig)
|
|
76
117
|
: null;
|
|
118
|
+
const restoredMinimaxConfigPath = minimaxWrite ? null : await restoreExistingMinimaxConfig(installedPath, existingMinimaxConfig);
|
|
77
119
|
|
|
78
120
|
return {
|
|
79
121
|
skillName: SKILL_NAME,
|
|
122
|
+
tool: options.tool || "codex",
|
|
80
123
|
sourcePath,
|
|
81
124
|
installedPath,
|
|
82
|
-
minimaxConfigPath: minimaxWrite ? minimaxWrite.configPath :
|
|
125
|
+
minimaxConfigPath: minimaxWrite ? minimaxWrite.configPath : restoredMinimaxConfigPath,
|
|
83
126
|
minimaxConfig: minimaxWrite ? redactMinimaxConfig(minimaxWrite.config) : null,
|
|
84
127
|
};
|
|
85
128
|
}
|
|
129
|
+
|
|
130
|
+
export async function installSkillToTargets(options = {}) {
|
|
131
|
+
const sourcePath = options.sourcePath || join(packageRoot, "skills", SKILL_NAME);
|
|
132
|
+
|
|
133
|
+
if (options.targetRoot) {
|
|
134
|
+
const install = await installSkill({
|
|
135
|
+
...options,
|
|
136
|
+
sourcePath,
|
|
137
|
+
tool: "custom",
|
|
138
|
+
});
|
|
139
|
+
return {
|
|
140
|
+
skillName: SKILL_NAME,
|
|
141
|
+
sourcePath,
|
|
142
|
+
installs: [install],
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
const env = options.env || process.env;
|
|
147
|
+
const installs = [];
|
|
148
|
+
|
|
149
|
+
for (const target of [
|
|
150
|
+
{ tool: "codex", targetRoot: resolveCodexSkillsRoot(env) },
|
|
151
|
+
{ tool: "claude-code", targetRoot: resolveClaudeCodeSkillsRoot(env) },
|
|
152
|
+
]) {
|
|
153
|
+
installs.push(await installSkill({
|
|
154
|
+
...options,
|
|
155
|
+
env,
|
|
156
|
+
sourcePath,
|
|
157
|
+
targetRoot: target.targetRoot,
|
|
158
|
+
tool: target.tool,
|
|
159
|
+
}));
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
return {
|
|
163
|
+
skillName: SKILL_NAME,
|
|
164
|
+
sourcePath,
|
|
165
|
+
installs,
|
|
166
|
+
};
|
|
167
|
+
}
|
package/package.json
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "hyper-animator-codex",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "Install the Hyper Animator
|
|
3
|
+
"version": "0.7.1",
|
|
4
|
+
"description": "Install the Hyper Animator skill for Codex and Claude Code.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
7
7
|
"hyper-animator-codex": "bin/hyper-animator-codex.mjs"
|
|
8
8
|
},
|
|
9
9
|
"scripts": {
|
|
10
|
+
"postinstall": "node bin/postinstall.mjs",
|
|
10
11
|
"test": "node --test",
|
|
11
12
|
"pack:check": "npm pack --dry-run"
|
|
12
13
|
},
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: hyper-animator-codex
|
|
3
|
-
description: Use when a user asks Codex to create, plan, author, customize, validate, preview, or render a HyperFrames, HTML, or GSAP animation/video from natural-language requirements, including product demos, code demos, data videos, podcast captions, social shorts, catalog assembly, new HyperFrames HTML, sound effects, background music, rhythm, BPM, or beat-synced transitions.
|
|
3
|
+
description: Use when a user asks Codex to create, plan, author, customize, validate, preview, or render a HyperFrames, HTML, or GSAP animation/video from natural-language requirements, including product demos, code demos, data videos, podcast captions, social shorts, catalog assembly, new HyperFrames HTML, outline/narration detection, voiceover, subtitles, sound effects, background music, rhythm, BPM, final mixing, or beat-synced transitions.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Hyper Animator Codex
|
|
@@ -12,23 +12,25 @@ Turn a natural-language animation or video brief into a validated HyperFrames HT
|
|
|
12
12
|
## Required Flow
|
|
13
13
|
|
|
14
14
|
1. Read `references/git-checkpoint-workflow.md` and run `scripts/git_checkpoint.mjs --phase init --message "chore: initialize hyper animator workspace" --allow-empty` before requirement capture. If the helper reports an existing dirty repository or linked worktree, stop and ask the user to resolve it.
|
|
15
|
-
2.
|
|
16
|
-
3.
|
|
17
|
-
4.
|
|
18
|
-
5.
|
|
19
|
-
6.
|
|
15
|
+
2. When starting in a new directory, restarting, or handling outline/narration/voiceover/subtitle/full-mix work, read `references/narration-audio-workflow.md` and run `scripts/detect_project_files.mjs --dir . --pretty` before visual planning.
|
|
16
|
+
3. Capture the raw request and extract an initial intent profile: purpose, format, duration, content inputs, style tags, motion tags, and needed roles.
|
|
17
|
+
4. If purpose, format, or core content is unclear, ask the first clarification round before choosing catalog items.
|
|
18
|
+
5. Read `references/hyperframes-catalog-map.json` and score candidates by keyword, intent domain, format, role, style, motion, and constraints.
|
|
19
|
+
6. Pick candidate blocks/components for main scene, caption, effects, transitions, and outro.
|
|
20
|
+
7. Decide generation mode:
|
|
20
21
|
- `generate_new_hyperframes_html` when the user asks to write HTML, create a new effect, customize style, match a brand, use complex animation, or when component snippets are only paste placeholders.
|
|
21
22
|
- `assemble_existing_catalog_items` only when the user asks to use existing catalog items or quickly compose installed blocks/components.
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
23
|
+
8. Clarify audio: ask whether to use narration, subtitles, animation/transition sound effects, and background music.
|
|
24
|
+
9. If narration is used, use `scripts/generate_minimax_tts.mjs` for voice listing and TTS. Do not construct MiniMax TTS HTTP calls directly. If subtitles are requested, run `scripts/generate_subtitles.mjs`.
|
|
25
|
+
10. If background music is requested or undecided, read `references/minimax-music-workflow.md` and use `scripts/generate_minimax_music.mjs` for every MiniMax music request. Do not construct MiniMax music HTTP calls directly. If MiniMax is unavailable or declined, ask for a local audio path or continue without BGM.
|
|
26
|
+
11. If background music is used, read `references/beat-sync-workflow.md`, generate or obtain the audio, and run `scripts/analyze_music_beats.py` when the file is available.
|
|
27
|
+
12. Ask the second clarification round with candidate context: visual direction, motion rhythm, generation mode, narration/subtitle/audio choices, music prompt/model when MiniMax is used, and beat-sync assumptions when background music is present.
|
|
28
|
+
13. Write or assemble HTML. When beat-sync is enabled, align major reveals, cuts, transitions, camera moves, narration beats, subtitle cues, and visual accents to the beat map instead of arbitrary timestamps.
|
|
29
|
+
14. After each file-writing stage, run `scripts/git_checkpoint.mjs` with the phase-specific allowlist from `references/git-checkpoint-workflow.md`. Do not create, switch, or recommend Git branches or worktrees.
|
|
30
|
+
15. Run pre-render quality gates on the base HTML.
|
|
31
|
+
16. Read `references/preview-controls-workflow.md`, run `scripts/inject_preview_controls.mjs` to create a preview HTML copy, and run `scripts/validate_hyperframes_html.py preview.html --preview-controls`.
|
|
32
|
+
17. Show a concise plan summary and preview path or HTML file to the user. Ask for confirmation before video render.
|
|
33
|
+
18. Render only after user confirmation. Prefer rendering the base HTML; if rendering the preview copy, use `?render=1`, `?preview=0`, or `<html data-render-mode="video">` so preview controls are hidden. Then report output path and any caveats.
|
|
32
34
|
|
|
33
35
|
## Interactive Questions
|
|
34
36
|
|
|
@@ -36,14 +38,15 @@ Prefer Codex interactive question tools such as `AskUserQuestion` or `request_us
|
|
|
36
38
|
|
|
37
39
|
Use two rounds:
|
|
38
40
|
|
|
39
|
-
- Round 1: purpose, format, duration, platform, required content, brand assets, sound effects, background music, and whether video render is expected in this turn.
|
|
40
|
-
- Round 2: after catalog scoring, ask about style, motion, candidate selection, generation mode, and beat-sync assumptions when background music is present.
|
|
41
|
+
- Round 1: purpose, format, duration, platform, required content, outline/narration status, narration/subtitles, brand assets, sound effects, background music, and whether video render is expected in this turn.
|
|
42
|
+
- Round 2: after catalog scoring, ask about style, motion, candidate selection, generation mode, voice/emotion/subtitle style, and beat-sync assumptions when background music is present.
|
|
41
43
|
|
|
42
44
|
Do not ask everything upfront when the brief is already specific. Ask only for missing or decision-changing information.
|
|
43
45
|
|
|
44
46
|
## References
|
|
45
47
|
|
|
46
48
|
- Read `references/git-checkpoint-workflow.md` before any `/hyper-animator` run writes files or initializes output.
|
|
49
|
+
- Read `references/narration-audio-workflow.md` when first-run detection, restart, outline, narration, voiceover, subtitle, BGM timing, or final audio/video mixing is mentioned.
|
|
47
50
|
- Read `references/hyperframes-intent-workflow.md` for the full AskUserQuestion workflow, generation-mode rules, scoring model, and render confirmation requirements.
|
|
48
51
|
- Read `references/hyperframes-catalog-map.json` whenever selecting catalog candidates or determining visual references.
|
|
49
52
|
- Read `references/hyperframes-agent-pseudocode.ts` when implementing the end-to-end loop or when the correct sequence is ambiguous.
|
|
@@ -94,7 +97,9 @@ If the validator fails, fix the HTML before asking the user to approve render.
|
|
|
94
97
|
Before rendering, summarize:
|
|
95
98
|
|
|
96
99
|
- generation mode;
|
|
100
|
+
- detected outline/narration paths, ambiguity status, and any outline/narration generation assumptions;
|
|
97
101
|
- selected or referenced catalog items;
|
|
102
|
+
- narration usage, selected voice, emotion, voice audio path, subtitle style, subtitle JSON/SRT paths, and voice/BGM/SFX volume values when applicable;
|
|
98
103
|
- sound effects and background music choices;
|
|
99
104
|
- MiniMax provider status, model, generated audio path, metadata path, and redacted config source when MiniMax is used;
|
|
100
105
|
- beat map path, BPM, duration, and timing assumptions when beat-sync is enabled;
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
# Narration Audio Workflow
|
|
2
|
+
|
|
3
|
+
Use this when a `/hyper-animator` run starts in a new directory, the user asks to restart, or the brief mentions outline, narration, voiceover, subtitles, BGM, beat sync, sound effects, or final audio/video mixing.
|
|
4
|
+
|
|
5
|
+
## Start Or Restart
|
|
6
|
+
|
|
7
|
+
Run file detection before visual planning:
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
node scripts/detect_project_files.mjs --dir . --pretty
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
Rules:
|
|
14
|
+
|
|
15
|
+
- scan only the current directory top level;
|
|
16
|
+
- trust fixed names first: `outline.*` and `narration.*`;
|
|
17
|
+
- if multiple candidates are returned, ask the user to choose;
|
|
18
|
+
- if only outline exists, ask whether to generate narration from it;
|
|
19
|
+
- if only narration exists, ask whether to generate an outline from it;
|
|
20
|
+
- if narration is not used, do not generate voice audio or subtitles.
|
|
21
|
+
|
|
22
|
+
Codex writes or edits outline/narration content. Scripts only validate, convert, call MiniMax, and write artifacts.
|
|
23
|
+
|
|
24
|
+
## Narration JSON
|
|
25
|
+
|
|
26
|
+
Use this shape:
|
|
27
|
+
|
|
28
|
+
```json
|
|
29
|
+
{
|
|
30
|
+
"voice": "XiaoR_001",
|
|
31
|
+
"emotion": "calm",
|
|
32
|
+
"language": "zh",
|
|
33
|
+
"style": "casual",
|
|
34
|
+
"scenes": [
|
|
35
|
+
{
|
|
36
|
+
"scene": 1,
|
|
37
|
+
"title": "Scene title",
|
|
38
|
+
"sync_hint": "Visual sync hint",
|
|
39
|
+
"narration": "Spoken text",
|
|
40
|
+
"duration_estimate": 8
|
|
41
|
+
}
|
|
42
|
+
]
|
|
43
|
+
}
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
Before generating narration, ask language and style. Default language is `zh`.
|
|
47
|
+
|
|
48
|
+
## MiniMax Voice
|
|
49
|
+
|
|
50
|
+
Do not hand-write MiniMax TTS HTTP calls. Use:
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
node scripts/generate_minimax_tts.mjs --list-voices --voice-type all
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
Prefer cloned voices, then generated voices, then system voices. Recommend three candidates by content tone and ask the user to choose. If listing fails, continue with `XiaoR_001` after telling the user.
|
|
57
|
+
|
|
58
|
+
Emotion labels:
|
|
59
|
+
|
|
60
|
+
```text
|
|
61
|
+
happy, sad, angry, fearful, disgusted, surprised, calm, fluent, whipser
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
Generate narration audio:
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
node scripts/generate_minimax_tts.mjs \
|
|
68
|
+
--narration-json narration.json \
|
|
69
|
+
--output-dir hyper-animator-output/voice
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
Use `--dry-run` before a real call when checking request shape or credentials.
|
|
73
|
+
|
|
74
|
+
## Subtitles
|
|
75
|
+
|
|
76
|
+
Generate subtitles only when narration is used and the user wants subtitles:
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
node scripts/generate_subtitles.mjs \
|
|
80
|
+
--narration narration.json \
|
|
81
|
+
--output-dir hyper-animator-output/subtitles \
|
|
82
|
+
--style clean
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
Subtitle rules:
|
|
86
|
+
|
|
87
|
+
- short phrase cues;
|
|
88
|
+
- no trailing punctuation;
|
|
89
|
+
- one visible cue at a time;
|
|
90
|
+
- JSON and SRT outputs include timecodes.
|
|
91
|
+
|
|
92
|
+
## BGM, Beat, And Schedule
|
|
93
|
+
|
|
94
|
+
BGM is the timing source when present:
|
|
95
|
+
|
|
96
|
+
1. decide BGM generation, local import, or skip;
|
|
97
|
+
2. if configured, generate BGM with `scripts/generate_minimax_music.mjs`;
|
|
98
|
+
3. analyze the music with `scripts/analyze_music_beats.py`;
|
|
99
|
+
4. schedule transitions, animation, narration, and subtitles against the beat map;
|
|
100
|
+
5. generate HTML;
|
|
101
|
+
6. preview and get user confirmation;
|
|
102
|
+
7. render and mix final video/audio.
|
|
103
|
+
|
|
104
|
+
Default mix:
|
|
105
|
+
|
|
106
|
+
- voice: `1.0`;
|
|
107
|
+
- BGM: `0.3`;
|
|
108
|
+
- SFX: `0.3`.
|
|
109
|
+
|
|
110
|
+
If the user gives volume commands, adjust `voice`, `bgm`, and `sfx` independently in the final mix command or render handoff.
|