npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

syncast-cli

v0.3.13

Published

Syncast CLI — AI generation and agent integration for Syncast

Downloads

90

Readme

syncast-cli

Syncast CLI — AI image/video/audio generation and agent integration for Syncast.

Choose the workflow before generation

An external Agent must determine whether the user is working in a Syncast project or only wants independent assets to review outside a project. If the request is unclear, ask before generating.

  • Project work: connect the intended page with syncast project-agent, inspect it, and run generation through public project Actions. Use syncast.imagine.submit when no existing channel was specified. Never fall back to the direct generation commands, including their --project options.
  • Standalone assets: use syncast imagine, video, audio, music, or sound-effect only after the user explicitly chooses assets for external viewing or requests the standalone API.

Installation

npm install -g syncast-cli
# provides both `syncast` and `syncast-cli` commands

Standalone quick start

These examples are only for the explicitly selected standalone-asset route.

# 1. Log in (device authorization in browser)
syncast auth login

# 2. Verify
syncast auth status

# 3. Generate an image (defaults to Nano Banana 2)
syncast imagine --prompt "a cat on the moon"

# Generate with a local reference image
syncast imagine -p "turn this into a studio product photo" --reference-image ./reference.png

# Generate a custom-size image, e.g. 4x6 inch at 600 DPI
syncast imagine -p "passport photo" --model seedream-5-0 --resolution custom --width 2400 --height 3600

# Generate with Seedream 5.0 Pro image editing/fusion
syncast imagine -p "precise commercial product poster" --model seedream-5-0-pro --resolution 1K

# Call OpenAI's official GPT Image 2 route explicitly
syncast imagine -p "precise bilingual launch poster" --model oai-gpt-image-2 --aspect-ratio 16:9 --resolution 2K --quality auto

# 4. Generate a video (defaults to KittyVibe Seedance 2.0 Pro)
syncast video --prompt "ocean waves at sunset"

# 5. Generate a complete audio clip with SeedAudio
syncast audio --prompt "一段 60 秒悬疑刑侦广播剧,电话对白,低音量悬疑音乐,结尾有汽车刹车和高跟鞋脚步声"

# Use a reference voice
syncast audio -p "爷爷(70岁以上,沙哑慈祥,饰演者为 @Audio1)慢慢说道:“今天爷爷什么都买给你。”" --reference-audio ./grandpa.wav

# 6. Generate music (defaults to Suno v5.5)
syncast music --prompt "温暖克制的电影配乐,缓慢钢琴与弦乐,逐渐进入宽广副歌"

# Generate an instrumental track
syncast music --prompt "retro synthwave chase theme, 118 BPM, cinematic build" --instrumental

# 7. Generate a sound effect
syncast sound-effect --prompt "distant muffled thunder, low deep rumbling, intermittent thunderclaps, no voices, no music"

Commands

| Command | Description | |---------|-------------| | syncast auth login | Device authorization login | | syncast auth status | Check session | | syncast auth logout | Clear local session | | syncast imagine | Image generation | | syncast video | Video generation | | syncast audio / syncast seedaudio | Complete audio generation with SeedAudio | | syncast music / syncast suno | Music generation with Suno v5.5 by default | | syncast sound-effect / syncast sfx | Sound effect generation | | syncast task status <id> | Task status / SSE stream | | syncast task cancel <id> | Cancel task | | syncast project-agent serve | Local bridge for external agents operating an opened frontend project | | syncast project-agent run <action> | Forward a Syncast Agent Action into the connected project page | | syncast project-agent notifications | List Agent Action notifications, including pending approvals | | syncast project-agent approval respond <id> | Approve or deny an internal Agent action approval | | syncast project-agent wait --ref <json> | Wait for a frontend Agent Action task ref | | syncast library guide [type] | Print package fields, compatibility rules, and canonical examples without login | | syncast library publish/import/export/share/status/approvals | Publish, package, share, import, and review reusable library resources | | syncast sync / start | Local file sync (legacy) |

Project work

Connect and inspect the target project before any generation:

syncast project-agent serve
syncast project-agent pages
syncast project-agent run syncast.project.inspect --input '{"limit":10}'
syncast project-agent capabilities --action syncast.imagine.submit --disclosure full
syncast project-agent run syncast.imagine.submit \
  --input '{"modelType":"nano-banana-2","prompt":"生成角色设定图","targetAssetName":"角色A首帧"}'

syncast.imagine.submit automatically resolves or creates the Agent Imagine channel and persists prompts, parameters, tasks, results, and Assets. Use syncast.imagine.submitToChannel only when the user selected a real existing Imagine channel. Document Imagine blocks and timeline generation Slots use their dedicated project Actions.

The direct imagine --project/--folder/--reference-asset options remain low-level compatibility features for API integrations. They do not reproduce project interaction and are not the external-Agent route for project work.

Library resources

Library commands use the same resource model as the Syncast app. They support Agents, Skills, Prompt Templates, Imagine Optimize Presets, Project Specs, and Project Templates.

# Publish a local resource into your personal library
syncast library publish ./SKILL.md --type skill --target personal

# Inspect exact fields and copy a canonical package example (no login required)
syncast library guide agent
syncast library guide skill
syncast library guide project_template

# Submit a project template for public review
syncast library publish ./bundle.json --type project_template --target public

# Import or export a portable package
syncast library export <resourceId> --output ./exports/
syncast library import ./exports/my-agent.syncast-library.json --target personal

# Create a private share link, then let another user import it
syncast library share create <resourceId> --max-uses 3
syncast library share inspect <token>
syncast library share import <token> --target personal

# Check status
syncast library status list
syncast library status list --target team:<teamId> --item-id <itemId> --type project_template_bundle --status all
syncast library status list --target public
syncast library approvals list --team <teamId>
syncast library approvals approve <requestId> --team <teamId>

Exports, share links, and public submissions include the stored resource data. When prompt, instruction, or project-spec text is detected, CLI output includes a disclosure block listing the relevant fields so callers can review what is being shared or published.

syncast library guide [type] is the machine-readable source of truth for local resource package fields. In particular:

  • Agent skills entries use skill_id, skill_type, and explicit preload for new packages. preload: false keeps a Skill available for on-demand loading; true injects full instructions at startup. A missing legacy value is interpreted as true.
  • Agent allow_load_skills is a compatibility field for access to unselected project custom Skills. Set it explicitly to false for new packages unless the Agent intentionally needs the whole project custom-Skill catalog. false still permits every built-in Skill, selected custom Skills, their dependencies, and always_apply Skills; a missing legacy value remains true.
  • Custom Skill depends entries use only skill_id and skill_type; preload is not a dependency field.
  • Agent child_agents reference independent Agents by child_agent_id and may add alias, routing, handoff, and project-spec strategy metadata.
  • Project-template bundles should include every referenced custom Skill and child Agent. Applying the bundle in a project performs dependency preflight and two-phase Agent import.

The canonical Agent shape begins like this; use syncast library guide agent for every field and a complete example:

{
  "type": "agent",
  "id": "story-planner",
  "name": "Story Planner",
  "instructions": "Read the project spec, then return a structured plan.",
  "allow_load_skills": false,
  "skills": [
    { "skill_id": "docs", "skill_type": "builtin", "preload": false },
    {
      "skill_id": "continuity-checker",
      "skill_type": "custom",
      "preload": true
    }
  ]
}

Project template bundles

Users who publish reusable project packs through the CLI use the library route:

syncast library publish ./bundle.json --type project_template --target personal
syncast library publish ./bundle.json --type project_template --target public --source-project-id <projectId>

project_template is the product alias for the stored project_template_bundle type. Personal and team targets store the package data as a workspace library item; public targets submit the same data through typedData.content for review. A project template bundle can include Agents, Skills, Prompt Templates, Project Specs, and an optional project skeleton:

{
  "type": "project_template",
  "id": "short-drama-skeleton",
  "name": "Short Drama Skeleton",
  "agents": [{ "id": "writer" }],
  "standardProjectTemplate": {
    "schemaVersion": 1,
    "docs": [
      {
        "id": "story-bible",
        "title": "Story Bible",
        "body": "# Story Bible\n\nProduction rules."
      },
      {
        "id": "episode-outline",
        "parentId": "story-bible",
        "title": "Episode Outline",
        "body": "Scene beats."
      }
    ],
    "resourceDirs": [
      { "path": "References/Characters" },
      { "path": "Shots/Act 1" }
    ]
  }
}

Use camel-case standardProjectTemplate in new packages. The app and backend also accept legacy standard_project_template packages and preserve the skeleton when importing, exporting, sharing, or submitting for public review. If an old public submission was normalized before this field existed, republish or upsert that package so reviewers and other clients can receive the skeleton.

Project Agent bridge

project-agent is separate from the normal cloud generation commands. It is a thin transport into an already opened Syncast frontend project page. External agents should still read .agents/skills/syncast-agent-actions to decide which action to call and what JSON input to send.

Start the local bridge:

syncast project-agent serve

The command prints activation query parameters. Open or reload the Syncast project URL with those parameters once:

syncastAgentBridgeToken=...
syncastAgentBridgePort=23457

Then verify the page is connected and call project-local actions:

syncast project-agent pages
syncast project-agent capabilities
syncast project-agent capabilities --action syncast.agent.delegate --disclosure full
syncast project-agent capabilities --action syncast.imagine.submit --disclosure full
syncast project-agent capabilities --action syncast.imagine.submitToChannel --disclosure full
syncast project-agent capabilities --action syncast.docs.imagineBlocks.history --disclosure full
syncast project-agent run syncast.project.inspect --input '{"limit":10}'
syncast project-agent run syncast.doc.graphql --input '{"query":"query { agents { agents { id name model allowLoadSkills skills { skillId skillType preload } childAgents { childAgentId alias displayName } } } }"}'
syncast project-agent run syncast.doc.graphql --input '{"query":"mutation EnsureDocs($inputs: [EnsureDocPageInput!]!) { ensureDocPages(inputs: $inputs) { success logicalKey docId created adopted contentWritten ready hasMeaningfulContent } }","variables":{"inputs":[{"logicalKey":"short-drama:episodes","title":"分集剧本","containerOnly":true},{"logicalKey":"short-drama:episode:01","title":"第一集","parentLogicalKey":"short-drama:episodes","initialMarkdown":"# 第一集\n\n## 场景一\n\n正文"}]}}'
syncast project-agent run syncast.agent.delegate --input '{"goal":"整理项目方案","executor":{"kind":"model","model":"gemini-3.8-flash"},"wait":false}'
syncast project-agent run syncast.agent.delegate --input '{"goal":"按专业配置整理项目方案","executor":{"kind":"agent","agentId":"project-agent-id"},"wait":false}'
syncast project-agent run syncast.imagine.submit --input '{"modelType":"nano-banana-2","prompt":"生成角色设定图","targetAssetName":"角色A"}'
syncast project-agent run syncast.imagine.submitToChannel --input '{"channelId":"imagine-channel-id","modelType":"nano-banana-2","prompt":"生成角色设定图","targetAssetName":"角色A"}'
syncast project-agent run syncast.docs.imagineBlocks.submit --input '{"docId":"doc-id","blockId":"block-id"}'
syncast project-agent run syncast.docs.imagineBlocks.history --input '{"docId":"doc-id","blockId":"block-id","disclosure":"full"}'
syncast project-agent wait --ref '{"kind":"agent_chat","projectId":"..."}' --return-result

Project document creation uses the generic syncast.doc.graphql bridge rather than a second CLI-specific document command. New content pages must use one ensureDocPages mutation with stable project-business logicalKey values and meaningful initialMarkdown; use parentLogicalKey to build a tree in the same batch. For an existing target, query its real id and pass existingDocId. Do not guess identity from titles or silently create a duplicate. success=true and ready=true are the persisted-content postcondition, so a mechanical read-back is unnecessary. The full internal GraphQL schema retains createDocPage only for App and historical blank-page callers; external syncast.doc.graphql rejects that compatibility field.

The bridge is mandatory whenever the user is working in a Syncast project, including a new or empty project. Project Imagine submission is a public interaction action, not a duplicate direct-generation API: syncast.imagine.submitToChannel reuses the frontend enqueue path and persists prompt, parameters, task state, and results in the selected Imagine channel. syncast.imagine.submit uses the same persistence path and is the default when no existing channel was specified because it resolves or creates the Agent Imagine channel automatically. The absence of an explicit channel-history request is not permission to leave the project workflow. Direct generation commands are only for a separately confirmed standalone-asset task.

Document Imagine cards keep an editable root plus independent frozen generation versions. syncast.docs.imagineBlocks.submit { docId, blockId } always creates another version, including while older versions are running or after results already exist. submitBatch without blockIds keeps the top-bar “generate all pending” behavior; explicit blockIds create another version for those blocks in parallel. Each successful submission returns its own task ref.

Read the authoritative history before choosing a result:

syncast project-agent run syncast.docs.imagineBlocks.history \
  --input '{"docId":"doc-id","blockId":"block-id","disclosure":"full"}'

The response contains stable versions[].results[] refs. Copy one result object unchanged into selectResult to change the current preview, or fixAsAsset to land that exact result as a normal document Asset block:

syncast project-agent run syncast.docs.imagineBlocks.selectResult \
  --input '{"docId":"doc-id","blockId":"block-id","result":{"channelId":"channel-id","messageId":"version-message-id","resultIndex":0,"assetId":"asset-id"}}'

syncast project-agent run syncast.docs.imagineBlocks.fixAsAsset \
  --input '{"docId":"doc-id","blockId":"block-id","result":{"channelId":"channel-id","messageId":"version-message-id","resultIndex":0,"assetId":"asset-id"}}'

Do not fix a result while another version is still running. A fixed Asset keeps its generation reference and can be restored later:

syncast project-agent run syncast.docs.imagineBlocks.restoreGeneration \
  --input '{"docId":"doc-id","blockId":"block-id"}'

Direct syncast imagine, ordinary channel submission, or manually patching Doc block state cannot replace this contract.

executor.kind=model uses a direct model and exposes every project Agent as a named option. executor.kind=agent uses one independent project Agent and exposes only its bound named Agents. Both can create a fresh ad-hoc child; child runs are leaves, and an ad-hoc child does not inherit parent Agent instructions. Query the Agents GraphQL module before selecting executor.agentId.

The CLI option --agent-id identifies the external operator connected through the bridge. It is not the same field as action input executor.agentId, which selects an internal project Agent.

When reading then updating an Agent, always request and preserve allowLoadSkills plus every skills.preload value. All built-in Skills remain available on demand. allowLoadSkills: false excludes only unselected project custom Skills; selected custom Skills, their dependencies, and alwaysApply Skills remain available. Omitting either boolean turns it into the legacy missing value, which is interpreted as true. A running task keeps the Agent/Skill snapshot captured at submission, so edits affect the next task. Child Agent permissions never exceed the root task permission ceiling.

The bridge and this README are external integration guidance. Do not copy CLI, Bridge, standalone API, syncast.* Action names, GraphQL mutations, transport, or access instructions into project-internal Skills, Agent instructions, project specs, prompt templates, or ordinary user documents unless the user explicitly asks for an integration document. Internal content should describe business rules, product-capability semantics, model ids, and creative parameters. Validate every text-bearing field, including descriptions and metadata, not only the body.

Delegate creative judgment such as ideation, script design, or an unknown structure. For complete user-provided text, use project GraphQL directly. For one or many exact edits in an existing document, use the structured action so the CLI does not need to guess the raw Patch DSL:

syncast project-agent run syncast.docs.replaceText \
  --input '{"docId":"doc-id","replacements":[{"search":"exact old text","replacement":"replacement text"}]}'

Every search must match exactly once; a missing or ambiguous match rejects the whole batch. Use raw patchDoc for line, section, or whole-document edits only after retrieving its complete string format from syncast.doc.graphql.explain. Preserve all supplied content. Custom Skill creation must query same-name Skills first, confirm alwaysApply, depends, and optional Agent binding, then read the complete Skill back by its real id and validate all document references plus instructions, description, and metadata.

The default output is stable JSON for agents. project-agent wait --return-result returns a compact result by default: final text, terminal task status, and artifact ids, with the final text at data.result.text. Add --full-result only for debugging the complete message, thinking, parts, and tool trace. For a readable terminal summary, add --format human.

CLI update guidance

Project Agent bridge responses may include a machine-readable cliUpdate object with an update command and a bridge restart command:

{
  "cliUpdate": {
    "code": "cli_update_available",
    "updateCommand": "npm install -g syncast-cli@latest",
    "restartCommand": "syncast project-agent serve"
  }
}

Most CLI releases do not require any frontend change. The CLI checks npm for syncast-cli@latest, so normal bug fixes and non-bridge features are announced by the CLI itself after the package is published.

Only bump the frontend Project Agent recommended CLI version when the current frontend depends on a newer project-agent bridge contract, activation parameter, or action result shape. This keeps old CLI clients informed through the opened frontend page without nagging users for unrelated CLI releases.

When a delegated internal Agent pauses on an approval request, list pending approval notifications and respond as the same external Agent identity:

syncast project-agent notifications --type agent_action.approval_requested --limit 5
syncast project-agent approval respond <approvalId> --approve
syncast project-agent approval respond <approvalId> --deny --feedback "User rejected this action."

Approval notifications also include a respondAction object that can be used directly with syncast project-agent run if the caller wants to stay fully generic.

The bridge does not expose arbitrary browser JavaScript or UI automation. It only forwards structured requests to window.__syncastAgent in the registered project page.

Output format

Default: JSON (agent-friendly). Use --format human for readable text.

syncast imagine -p "hello" --format human

Generation defaults

Syncast's default image model is nano-banana-2. Text-to-image, reference-image generation, and ordinary image editing should all be treated as the same image input capability family: use the image-input fields supported by the current schema instead of splitting "reference" and "edit" into separate model families. Use oai-gpt-image-2 when a task explicitly needs OpenAI/GPT Image 2, mask editing, official API behavior, or strict output controls.

The CLI deliberately does not keep a second model allowlist. Omitting --model uses the recommended defaults above; an explicit --model <backend-model-type> is normally passed to the server registry, so specialized models remain available without waiting for a CLI release. The retired Seedance aliases seedance2.0pro and seedance2.0fast are the exception: the CLI rewrites them to kittyvibe-seedance2.0pro and kittyvibe-seedance2.0fast, respectively. The same rewrite applies when model_type is supplied through --input or --input-file. Explicit models do not inherit the default command's aspect-ratio, resolution, or duration values.

For the standalone-asset route, direct syncast imagine supports schema passthrough:

# Reuse a local image outside a project
syncast imagine -p "poster layout" --reference-image ./reference.png

# Read the same passthrough object from a file
syncast imagine -p "poster layout" --input-file ./input.json

If the source is already a Syncast project Asset, stay in the project workflow and pass its stable Asset ID through syncast.imagine.submit. If a required local file is not yet in the project, ask the user to import it there rather than silently switching to standalone generation.

Syncast's default video model family is KittyVibe Seedance 2.0. Use kittyvibe-seedance2.0pro for normal text-to-video, image-to-video, and multi-reference/multimodal video; use kittyvibe-seedance2.0fast for fast/low-cost previews; use Global variants for complex action or high-motion scenes. Do not switch to other video models only because the user provides images or asks for references.

syncast video also accepts --input and --input-file, so model-specific video parameters such as content, images, first_frame, last_frame, or an upscale source can be supplied directly when an explicitly selected model needs them.

Syncast's direct complete-audio model is SeedAudio 1.0 (bytedance/seed-audio-1.0). Use syncast audio for voiceover, dubbing, audio drama, multi-character dialogue, narration with ambience/SFX/BGM, and reference-audio continuation or gap filling. Keep syncast sound-effect for short one-shot SFX and loopable ambience. The --duration value maps to target_duration_seconds (30-120 seconds) for prompt guidance and cost estimate; fal does not currently expose a hard duration parameter for this endpoint. The final prompt must stay within 2048 characters, including the automatic duration hint. Each audio reference must be 30s or shorter and 10MB or smaller; image references must be 10MB or smaller.

# Complete audio scene
syncast audio -p "一段约 60 秒的雨夜霓虹小巷影视级音频场景。雨声和远处车流声作为背景声床,低音量合成器音乐压在对白下方。"

# Up to 3 audio references, addressed as @Audio1, @Audio2, @Audio3 in the prompt
syncast audio -p "@Audio1 饰演林,@Audio2 饰演赵。生成一段约 45 秒的中文电梯对峙音频,背景有低沉通风声。" --duration 45 --reference-audio ./lin.wav --reference-audio ./zhao.wav

# Or one image reference, not mixed with audio references
syncast audio -p "使用参考图片作为视觉氛围和声音场景参考。生成清晨雪地火车站音频。" --reference-image ./station.png

# Passthrough advanced fields
syncast audio -p "A clean narration." --input '{"voice":"cedric_en_zh","output_format":"wav","sample_rate":44100}'

Syncast's default music model is Suno v5.5 (zhenzhen-suno-v5.5). Use syncast music for songs, instrumentals, BGM, scores, hooks, lyrics, continuation, and cover workflows. Lyria remains available only as an explicitly selected alternative model through --model lyria-3-clip or --model lyria-3-pro.

# Natural-language music generation; mode defaults to description
syncast music -p "Mandarin indie-pop song, warm female vocal, restrained verse, expansive chorus, live drums and shimmering guitars"

# Instrumental BGM
syncast music -p "tense investigative documentary underscore, muted piano, low strings, subtle pulse" --instrumental

# Custom lyrics: prompt contains final lyrics, tags contain the music/style brief
syncast music --mode custom --lyrics-mode manual --title "夜航" --tags "Mandarin synth-pop, 112 BPM, female vocal, cinematic chorus" -p $'[Verse]\n城市在脚下退后\n[Chorus]\n我们沿着夜色远航'

# Continue or cover one local audio reference
syncast music --mode extend --continue-at 28 --reference-audio ./source.mp3 -p "Continue with the same key and vocal character, then build into a larger final chorus"
syncast music --mode cover --reference-audio ./source.mp3 --tags "acoustic folk, intimate male vocal" -p "Reinterpret the source as a sparse acoustic performance"

Use syncast audio rather than syncast music when the result is primarily dialogue, dubbing, narration, radio drama, or a mixed sound scene. Use syncast sound-effect for isolated effects and ambience. For clean reusable long-form TTS or voice cloning/design, select the corresponding MiniMax model explicitly through syncast audio --model ... --input ....

The Agent skill is the operational guide for agents. When the CLI exposes machine-readable generation schema, agents should use it as the source of truth for supported media-input fields and examples.

Configuration

  • File: ~/.syncast/config.json
  • Env: SYNCAST_API_URL or API_URL (default http://localhost:8901)

Agent / Cursor skill

See .agents/skills/syncast-cli/SKILL.md for agent installation instructions.

The CLI package and Agent skills are updated separately. Before using syncast project-agent, refresh the project skill from the published skill repo if it is missing or stale:

npx skills add latentcat/syncast-skills --skill syncast-agent-actions -y

Example prompt for agents:

Help me install Syncast CLI and log in, then generate a test sound effect.

Development

bun install
bun run build
node dist/cli.js --help

License

MIT

Workspace status and approval lists use a metadata-only endpoint (requires the matching backend update). Exact --item-id lookup avoids searching a truncated list. Reads share a 25-second overall deadline and retry a transport/gateway failure at most once; publications have a 90-second deadline and are never automatically replayed. If a publication response is lost, check its ID, version and status before retrying: a matching status alone does not prove that a particular attempted payload committed. Full resource reads and exports still fetch complete snapshots.