@docyrus/animaguru 0.10.0 → 0.13.0

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@docyrus/animaguru",
3
- "version": "0.10.0",
3
+ "version": "0.13.0",
4
4
  "description": "Agent-friendly AnimaGuru CLI built with CrustJS",
5
5
  "type": "module",
6
6
  "bin": {
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: animaguru
3
- description: Use the AnimaGuru CLI to create and animate assets, scaffold video workspaces, and submit finished HTML5 animations or MP4s for public or selected-user sharing.
3
+ description: Use the AnimaGuru CLI to create and animate assets, create HeyGen avatars, scaffold video workspaces, and submit finished HTML5 animations or MP4s for public or selected-user sharing.
4
4
  ---
5
5
 
6
6
  # AnimaGuru
@@ -33,6 +33,8 @@ Read the project ID from `projects create` and job IDs from submission responses
33
33
 
34
34
  Generation and reference imports spend credits and require `--yes`. Use it for work the user has authorized, respecting any budget or model constraints. Creating or installing this skill grants no spending authorization. Estimates are ranges; actual provider usage determines charges. Project deletion also requires `--yes` and should follow the user's request to delete that project.
35
35
 
36
+ One AnimaGuru credit represents $0.01 of model cost. CLI/API balances, estimates, credit ranges and queued-job receipts already use these credits, including fractional amounts such as 0.7. This includes offline `--dry-run` estimates. Compare them directly with the user's credit budget; do not rescale returned amounts.
37
+
36
38
  `generate`, `jobs submit`, and `files import` accept optional `--image-model` and `--video-model` flags. These select models for that operation and its explicitly queued animations. Use `animaguru models PROJECT_ID --image-model IMAGE_ID --video-model VIDEO_ID` only when the user wants to change defaults for future jobs. Omitted selections use project defaults, then service defaults. Discover available identifiers from `catalog` rather than hardcoding model names.
37
39
 
38
40
  ## Animate, redraw, or import
@@ -83,6 +85,25 @@ For ElevenLabs speech, choose `eleven_v4` or `eleven_v4_turbo`, pass an ElevenLa
83
85
 
84
86
  Use `--dry-run` for local request validation and estimated credits without sign-in or paid work. The estimate does not prove the server has the provider, the credits, or the reference image. Use `--yes` only within the user's existing spending authorization. For file-based requests, write the API asset request as JSON and use `assets submit PROJECT_ID --file asset.json --yes`; `--model` overrides the file's selection. Jobs use the existing `jobs wait PROJECT_ID JOB_ID` workflow. After completion, read the asset id from `assets list` and download with `assets download PROJECT_ID ASSET_ID --output welcome.wav`, or export the complete project ZIP.
85
87
 
88
+ ## HeyGen avatars
89
+
90
+ CLI 0.13.0 adds `avatars`. Check `animaguru avatars --help` before using it with an installed CLI. A group is a character, its looks are outfits, poses or styles, and a look ID is what HeyGen renders with. `avatars list PROJECT_ID` browses HeyGen's public catalog from any project; `--ownership private` lists the avatars this project created, which only it can see or change. `avatars looks PROJECT_ID --group GROUP_ID` lists a character's looks, and `avatars templates` lists Look Pack and look template IDs.
91
+
92
+ ```sh
93
+ animaguru avatars create PROJECT_ID --type prompt --name "Ada" \
94
+ --prompt "Woman in her early 30s, warm smile, navy blazer, bright studio" --dry-run
95
+ animaguru avatars create PROJECT_ID --type prompt --name "Ada, keynote" \
96
+ --look LOOK_ID --prompt "On a conference stage under a spotlight" --dry-run
97
+ animaguru avatars create PROJECT_ID --type photo --name "Sam" \
98
+ --file IMAGE_SHA_URL_OR_PATH --subject-consent --dry-run
99
+ animaguru avatars add-looks PROJECT_ID --look LOOK_ID --template TEMPLATE_ID --dry-run
100
+ animaguru avatars wait PROJECT_ID LOOK_ID
101
+ ```
102
+
103
+ `--file` and `--reference-images` take a project file SHA, an HTTPS URL (up to 32 MB) or a local file (up to 8 MB). Photos and footage show a real person: pass `--subject-consent` only after the user confirms that person agreed to become an avatar, and do not make avatars of people the user has no permission to depict. A `digital_twin` trains on about two minutes of footage and also needs the person's own consent: run `avatars consent PROJECT_ID GROUP_ID`, give them the 24-hour link, and check `consentStatus` with `avatars get PROJECT_ID --group GROUP_ID`.
104
+
105
+ Avatars and looks are charged when HeyGen accepts them and need `--yes`; get the estimate with `--dry-run` first. New looks start `processing`: use `avatars wait` rather than creating them again. `avatars rename`, `avatars voice` (default voice) and `avatars delete --yes` change only the project's own avatars; deletion is permanent, so run it only when the user asks to delete that avatar.
106
+
86
107
  ## Wait and export
87
108
 
88
109
  ```sh
@@ -127,6 +148,22 @@ After MP4 export, inspect with `animaguru youtube upload --file FILE --title TIT
127
148
 
128
149
  Uploads run locally while the CLI is open. After interruption, use `youtube uploads list` and `youtube uploads resume UPLOAD_ID --yes` instead of starting another upload. Resumption uses the original file and settings and probes Google's persisted offset. `youtube auth logout --yes` revokes access and removes local credentials and receipts; videos remain on YouTube. No AnimaGuru backend, sign-in or generation credits are used.
129
150
 
151
+ ## Cloud sync and versions
152
+
153
+ CLI 0.11.0 adds `animaguru cloud` for users on Individual Pro or Team. Discover it in `animaguru schema`. Commands run from anywhere inside a video workspace; `--dir PATH` selects another folder.
154
+
155
+ Only link a folder when the user asks for cloud sync. `cloud link` creates a cloud project in the selected AnimaGuru workspace (`workspaces use` picks a team), and `cloud link --id PROJECT_ID` attaches an existing one. In a linked folder:
156
+
157
+ - Check `cloud status` before ending a working session.
158
+ - Save with `cloud push -m "MESSAGE"` at milestones the user would want to return to, such as an approved storyboard, finished scenes or an exported cut. Describe the change in the message.
159
+ - Pushing spends no generation credits but uploads files, so do not push secrets or private material the user excluded.
160
+ - When push reports a newer cloud version, run `cloud pull`.
161
+ - When pull stops on files changed on both sides, show them to the user. Ask before using `--prefer local` (keep theirs; the next push replaces the cloud copy) or `--prefer cloud` (take the cloud's; local copies go to `.animaguru/sync/backups/`).
162
+
163
+ `cloud versions` lists history. `cloud restore VERSION [--path P]` brings back an earlier version without rewriting history; then push to save it as the newest version. Restore refuses to replace unsaved changes unless `--yes`, and needs the user's go-ahead. `cloud clone PROJECT_ID DIR` downloads a project; run `npm install` there. `cloud delete PROJECT_ID --yes` permanently removes every version: run it only when the user asks to delete that cloud project.
164
+
165
+ Sync never uploads node_modules, exports, frames, `.env` files, credentials, keys, links or `.gitignore`/`.animaguruignore` matches. Add bulky regenerable files to `.animaguruignore` rather than deleting them. Images, video, audio and ZIP files are stored once in cloud storage at any size and count toward the plan's media storage (20 GB Pro, 100 GB per Team). Every other file is versioned in Git. A work file over 32 MB stops the push: tell the user, and ignore or move it only with their agreement. If the plan ended, pushing is refused, but pulling and cloning still work. Never read or print `.animaguru/sync/` tokens; the CLI requests short-lived Git credentials itself.
166
+
130
167
  ## Shared workspace commands
131
168
 
132
169
  Run tooling from the workspace root. `npm run dev` opens a hub with separate animation URLs. Use `npm run build -- --animation NAME`, `npm run export:html -- --animation NAME`, `npm run export:mp4 -- --animation NAME`, or `npm run review -- --animation NAME`. These select one film and save outputs/receipts under its `production/` directory. `npm run example -- STYLE_ID --animation NAME` installs an original study only when the selected film is untouched. Root `runtime/`, `scripts/`, skills and dependencies are shared infrastructure.
@@ -81,6 +81,10 @@ Use `src/studies/timing.ts` for analytic easing, measured stroke reveals and cue
81
81
  When the user requests hosting or sharing, use `animaguru submit --yes` from this workspace; it builds and submits the portable HTML5 animation. For an MP4 use `--file production/exports/film.mp4`; its `.vtt`/`.srt` subtitles beside it are uploaded too and shown by the AnimaGuru player, so submit the clean MP4 rather than a `-captioned.mp4`. Read the local AnimaGuru skill's submission section for audience, recipient and recovery rules. Private is the default; use `--share "reviewer@example.com"` for selected verified accounts or `--visibility public` for [the public Videos section](https://animaguru.com/videos). Preserve the user's audience choice and include a cover using `--poster` when available. Local creation or export alone does not imply publication.
82
82
 
83
83
 
84
+ ## Cloud versions
85
+
86
+ If the workspace has `.animaguru/sync/link.json`, it syncs with an AnimaGuru cloud project. Save milestones the user would want to return to with `animaguru cloud push -m "MESSAGE"`, such as an approved brief, finished scenes or a delivered export. Run `animaguru cloud pull` when push reports a newer version. Do not link a folder or delete a cloud project unless the user asks. Read the local AnimaGuru skill's cloud section for conflicts, restores and plan rules.
87
+
84
88
  ## Multi-animation workspace
85
89
 
86
90
  Detect root `animaguru.workspace.json`. For a new film, use `animaguru create animation NAME`; preserve other animation folders. Keep scenes, story copy, local media and production outputs in the selected folder. Read root `AGENTS.md` for shared commands and path mapping. Do not duplicate the player, exporter, skills or dependencies into films. New schema 4 projects inherit root branding and keep their own brief/category/style. Work from the root and pass `--animation NAME` to build, HTML5/MP4 export, review and example commands. For generated media helpers in a film under animations/NAME/src/, import from ../../../runtime/. Narration must be a configured local public asset and should be checked in hosted/embed playback as well as the editor.
@@ -32,3 +32,7 @@ Original 2.5D study recipes are in `src/studies/`. In an untouched starter, `npm
32
32
  ## Submit to AnimaGuru
33
33
 
34
34
  When asked to host or share the finished film, read the local AnimaGuru skill's submission section. `animaguru submit --yes` builds the portable HTML5 export and uploads it privately; `--file` accepts an existing HTML5 ZIP or MP4; an MP4's `.vtt`/`.srt` subtitles beside it are uploaded with it, so prefer the clean MP4 over a `-captioned.mp4`. `--share "reviewer@example.com"` selects verified AnimaGuru accounts, while `--visibility public` publishes to https://animaguru.com/videos and allows watching, downloading and HTML5 embedding. Include a cover with `--poster public/assets/cover.png` when available. Do not infer public sharing from a request to create or export a film. The CLI returns the hosted watch URL and video ID. Owners can change details and sharing from that page.
35
+
36
+ ## Cloud versions
37
+
38
+ A linked folder has `.animaguru/sync/link.json`. Save milestones the user would want to return to with `animaguru cloud push -m "MESSAGE"`; run `animaguru cloud pull` when push reports a newer cloud version. Ask before resolving files changed on both sides, restoring over unsaved work, linking a new folder or deleting a cloud project. The AnimaGuru skill's cloud section has the details.
@@ -101,3 +101,7 @@ Browse `animaguru.templates.json` for all 31 styles and purpose workflows. The e
101
101
  ## Share on AnimaGuru
102
102
 
103
103
  After signing in with `animaguru auth login`, run `animaguru submit --yes` here to build and host the finished HTML5 animation privately. Add `--share "reviewer@example.com"` to invite selected verified AnimaGuru accounts, or `--visibility public` to list it at [Videos](https://animaguru.com/videos). `--poster public/assets/cover.png` adds a cover. Already exported an MP4? Pass `--file production/exports/film.mp4`; the `.vtt` subtitles beside it are uploaded too, and the AnimaGuru player shows them over the picture with a CC button. The CLI returns your hosted player URL; public HTML5 animations can be embedded from that page. Owners manage details and access there. Only the exported player/media are uploaded.
104
+
105
+ ## Cloud versions
106
+
107
+ On Individual Pro or Team, `animaguru cloud link` creates a cloud project for this folder. `animaguru cloud push -m "What changed"` then saves a version, `animaguru cloud pull` brings in versions saved elsewhere, and `animaguru cloud clone PROJECT_ID` continues on another computer. `animaguru cloud restore VERSION` returns to an earlier version; push afterwards to keep it. Dependencies, exports, frames, `.env` files, credentials and anything in `.gitignore` or `.animaguruignore` stay local. The studio's Cloud page lists every version and its files.
@@ -17,5 +17,6 @@ Run commands from the workspace root:
17
17
  - `npm run review -- --animation NAME`: frame, text, seeking and soundtrack checks.
18
18
  - `npm run example -- STYLE_ID --animation NAME`: install a study only in an untouched selected film.
19
19
  - `animaguru submit animations/NAME --yes`: private hosting; choose recipients/public sharing from the user's request.
20
+ - `animaguru cloud push -m "MESSAGE"`: in a linked workspace, save every film and the shared kit as a cloud version; `animaguru cloud pull` brings in teammates' versions.
20
21
 
21
22
  Preserve the deterministic async seeking/frame API. Keep actual scene text and captions in the canvas, and align resources/cues with real assets and timing. Production files and export receipts stay with their animation. Shared infrastructure changes affect every film, so use those for reusable player/export improvements and keep film-specific direction inside its own folder. Follow the user's model and credit budget; workspace creation authorizes no paid generation.
@@ -11,5 +11,6 @@ production/frames/
11
11
  .DS_Store
12
12
 
13
13
  .animaguru/cache/
14
+ .animaguru/sync/
14
15
  animations/*/production/exports/
15
16
  animations/*/production/frames/
@@ -9,5 +9,5 @@ let port = 5195;
9
9
  if (rest.length) { if (rest.length !== 2 || rest[0] !== "--port" || !/^\d+$/.test(rest[1])) throw new Error("Usage: npm run dev -- [--animation NAME] [--port NUMBER]"); port = Number(rest[1]); }
10
10
  const workspace = await workspaceInfo(root);
11
11
  const context = animation ? await projectContext(root, animation) : null;
12
- const server = await createServer({ root, configFile: false, base: "./", publicDir: workspace ? false : undefined, server: { host: "127.0.0.1", port, strictPort: true }, plugins: [...(workspace ? [workspacePlugin(root)] : []), htmlExportPlugin(root)] });
12
+ const server = await createServer({ root, configFile: false, base: "./", publicDir: workspace ? false : undefined, server: { host: process.env.ANIMAGURU_HEADLESS === "1" ? "0.0.0.0" : "127.0.0.1", port, strictPort: true }, plugins: [...(workspace ? [workspacePlugin(root)] : []), htmlExportPlugin(root)] });
13
13
  await server.listen(); console.log(`AnimaGuru workspace: http://127.0.0.1:${port}${context?.route ?? "/"}`);
@@ -10,6 +10,7 @@ import ffprobe from "@ffprobe-installer/ffprobe";
10
10
  import { projectArguments, projectContext, publicFile } from "./project-context.mjs";
11
11
  import { workspacePlugin } from "./workspace-plugin.mjs";
12
12
  import { subtitleCues, toSrt, toVtt } from "./subtitles.mjs";
13
+ import { captureHeadless } from "./headless-browser.mjs";
13
14
 
14
15
  const root = fileURLToPath(new URL("../", import.meta.url));
15
16
  const selection = projectArguments(process.argv.slice(2));
@@ -243,3 +244,7 @@ process.once("SIGINT", () => { void cleanup(new Error("Cancelled.")); });
243
244
  process.once("SIGTERM", () => { void cleanup(new Error("Cancelled.")); });
244
245
  try { await server.listen(); } catch (error) { await cleanup(error); throw error; }
245
246
  console.log(`Open this local export page and keep it open until complete:\nhttp://127.0.0.1:${port}${context.route}?capture=1&export=${token}\nOutput: ${destination}\nThe preview can stay open. This capture runs locally without generation credits.`);
247
+ if (process.env.ANIMAGURU_HEADLESS === "1") {
248
+ try { await captureHeadless(`http://127.0.0.1:${port}${context.route}?capture=1&export=${token}`, { endpoint: "/__export/finish" }); }
249
+ catch (error) { await cleanup(error); }
250
+ }
@@ -0,0 +1,17 @@
1
+ /** Uses the same capture page and HTTP protocol as a locally opened browser. */
2
+ export async function captureHeadless(url, { endpoint, timeout = 30 * 60 * 1000 } = {}) {
3
+ const { chromium } = await import("playwright-core");
4
+ const browser = await chromium.launch({
5
+ executablePath: process.env.PLAYWRIGHT_CHROMIUM_EXECUTABLE_PATH ?? "/usr/bin/chromium",
6
+ headless: true, args: ["--no-sandbox", "--disable-dev-shm-usage", "--autoplay-policy=no-user-gesture-required"],
7
+ });
8
+ try {
9
+ const page = await browser.newPage({ deviceScaleFactor: 1 });
10
+ const finished = page.waitForResponse((response) => new URL(response.url()).pathname === endpoint, { timeout });
11
+ page.on("pageerror", (error) => console.error(`Capture page: ${error.message}`));
12
+ await page.goto(url, { waitUntil: "domcontentloaded", timeout: 60_000 });
13
+ const response = await finished;
14
+ if (!response.ok()) throw new Error(`Capture failed (${response.status()}): ${await response.text()}`);
15
+ await response.finished();
16
+ } finally { await browser.close(); }
17
+ }
@@ -7,6 +7,7 @@ import { projectArguments, projectContext } from "./project-context.mjs";
7
7
  import { workspacePlugin } from "./workspace-plugin.mjs";
8
8
  import { analyzeReview } from "./review-analysis.mjs";
9
9
  import { inspectAudio } from "./review-audio.mjs";
10
+ import { captureHeadless } from "./headless-browser.mjs";
10
11
 
11
12
  const root=fileURLToPath(new URL("../",import.meta.url));
12
13
  const selection=projectArguments(process.argv.slice(2));
@@ -39,3 +40,7 @@ const server=await createServer({configFile:false,root,base:"./",publicDir:conte
39
40
  });
40
41
  }}]});
41
42
  await server.listen();console.log(`Open this review page and keep it open until completion:\nhttp://127.0.0.1:${port}${context.route}?review=${token}`);
43
+ if(process.env.ANIMAGURU_HEADLESS==="1") {
44
+ try { await captureHeadless(`http://127.0.0.1:${port}${context.route}?review=${token}`,{endpoint:"/__review/report"}); }
45
+ catch(error) { console.error(error.message);process.exitCode=1;await server.close(); }
46
+ }