@assethub/cli 0.1.25 → 0.1.28
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 +104 -2
- package/dist/agentSetup.d.ts +69 -0
- package/dist/agentSetup.d.ts.map +1 -0
- package/dist/agentSetup.js +311 -0
- package/dist/execution.d.ts.map +1 -1
- package/dist/execution.js +19 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +255 -32
- package/dist/productionOneShot.d.ts +195 -0
- package/dist/productionOneShot.d.ts.map +1 -0
- package/dist/productionOneShot.js +307 -0
- package/dist/setup.d.ts +1 -0
- package/dist/setup.d.ts.map +1 -1
- package/dist/setup.js +1 -1
- package/package.json +3 -2
- package/skills/assethub/SKILL.md +151 -0
package/dist/index.d.ts
CHANGED
|
@@ -22,7 +22,7 @@ type CommandContext = {
|
|
|
22
22
|
*/
|
|
23
23
|
args: string[];
|
|
24
24
|
};
|
|
25
|
-
export declare const usage = "AssetHub CLI\n\nCLI and MCP are available to all AssetHub users. Workspace permissions and feature availability apply.\n\nUsage:\n assethub --version\n assethub doctor [--mcp] [--profile <name>] [--timeout-ms <n>]\n assethub mcp tools [tool-name] [--account] [--profile <name>] [--timeout-ms <n>]\n assethub mcp config --client cursor|codex [--account] [--base-url <url>]\n assethub auth login --api-key <key> [--base-url <url>] [--profile <name>]\n assethub auth login --api-key-stdin [--base-url <url>] [--profile <name>]\n assethub auth login --access-token-stdin [--base-url <url>] [--profile <name>]\n assethub auth status [--profile <name>]\n assethub auth logout [--profile <name>]\n assethub workspace list [--query <text>] [--limit <1-100>] [--cursor <cursor>]\n assethub workspace get\n assethub workspace create --name <name> [--operation-id <uuid>]\n assethub workspace use <workspace-id>\n assethub workspace members [--workspace <id>]\n assethub workspace invite --email <email> [--role user|admin] [--resend] [--workspace <id>]\n assethub workspace set-role <user-id> --role user|admin [--workspace <id>]\n assethub workspace remove-member <user-id> [--workspace <id>]\n assethub workspace prepare|sync|analyze|verify --internal --manifest <json> --state <json>\n assethub workspace self-check --internal\n assethub workspace context put --internal --org <uuid> --actor <uuid> --canvas <id> --file <json> [--if-version <n>] [--order <uuid>]\n assethub workspace context get --internal --org <uuid> --actor <uuid> --canvas <id> [--out <json>] [--order <uuid>]\n assethub project ingest <source-dir> --out-dir <directory> [--exclude-dir <relative-path>...]\n assethub language text|vision --input-json @<json> --operation-id <uuid> [--out <json>]\n assethub canvas download --canvas <id> --out-dir <directory> [--mesh <mesh_asset_id>]\n assethub canvas nodes --canvas <id>\n assethub canvas import --canvas <id> --file <image> [--name <name>]\n assethub canvas context get --canvas <id> [--out <json>]\n assethub canvas context put --canvas <id> --file <json> [--if-version <n>]\n assethub canvas layout --canvas <id> --input-json @<json>\n assethub canvas compare --canvas <id> --source-id <asset-id> --asset-id <asset-id> --out <html>\n assethub moodboard create --input-json @<json> [--operation-id <uuid>]\n assethub moodboard list|get|update|archive [<board-id>] [--input-json @<json>]\n assethub moodboard analyze <board-id> [--revision <uuid>] [--wait]\n assethub image generate --canvas <id> --context <id> [--context-version <n>] [--context-source <key>] [--moodboard-revision <uuid>] --prompt <text> --wait\n assethub models list [--domain <domain>] [--ids-only] [--limit <n>]\n assethub models get <model-id>\n assethub files import <url> --media-type image|mesh\n assethub files upload <file> --media-type image|mesh\n assethub source create (--file <path> | --source-url <url> | --source-id <id> | --stdin | --stdin-base64 | --stdin-data-uri | --stdin-json | --source-json <json|@file|@-> | --data-uri <uri> | --clipboard) --media-type image|mesh [--file-name <name>] [--content-type <type>]\n assethub capabilities\n assethub api search [query]\n assethub api describe \"<METHOD /path>\"\n assethub api call \"<METHOD /path>\" [--path-json <json|@file>] [--query-json <json|@file>] [--input-json <json|@file|@->] [--operation-id <uuid>]\n assethub skills list [--cursor <cursor>]\n assethub skills get <skill-id> [--revision <n>]\n assethub skills learn --input-json <json|@file|@-> --operation-id <uuid>\n assethub skills update <skill-id> --input-json <json|@file|@->\n assethub skills controls <skill-id> --revision <n> --grant-revision <n> --mode automatic|manual|off [--share]\n assethub skills prepare --input-json <json|@file|@->\n assethub skills proposal <proposal-id>\n assethub skills accept <proposal-id> --input-json <json|@file|@->\n assethub composer models\n assethub composer refine --list-modes\n assethub composer refine --from-run <run-id> --instruction <text> [--mode standard|thorough|placement|workshop|blender|codex] [--max-rounds <n>] [--transforms-json <json|@file>] [--wait] [--download --out-dir <dir>]\n assethub composer refine --input-json <json|@file> [--canvas <id>] [--operation-id <uuid>] [--wait] [--download --out-dir <dir>]\n assethub composer run --part <mesh-asset-id> [--part <mesh-asset-id>...] --reference <image-asset-id> [--model <id>] [--mode quick|quality] [--transforms-json <json|@file>] [--canvas <id>] [--wait]\n assethub composer run --input-json <json|@file> [--canvas <id>] [--operation-id <uuid>] [--wait] [--download --out-dir <dir>]\n assethub composer run --from-run <run-id> [--transforms-json <json|@file>] [--mode quick|quality] [--wait]\n assethub composer run --node <shape:id> --canvas <id> [--model <id>] [--mode quick|quality] [--operation-id <uuid>] [--wait]\n assethub canvas create [--name <name>] [--operation-id <uuid>]\n assethub canvas list [--cursor <cursor>] [--limit <n>]\n assethub canvas get|use|open [<id>]\n assethub runs list [--canvas <id>] [--cursor <cursor>] [--limit <n>]\n assethub runs get|watch <run-id> [--timeout-ms <n>]\n assethub runs resume <operation-id> [--wait]\n assethub graph list [--cursor <cursor>] [--limit <n>]\n assethub graph show|export [--canvas <id> | --graph <id>] [--source generated|upload] [--artifact <node-id>] [--out <path>] [--allow-truncated]\n assethub graph lineage --artifact <node-id> [--canvas <id> | --graph <id>] [--source generated|upload] [--direction ancestors|descendants|both] [--depth <n>] [--out <path>]\n assethub evaluate list\n assethub evaluations submit --artifact <asset-id> --report <json|file|@file|@-> [--agent <name>] [--canvas <id>] [--reference <asset-id>...] [--run <run-id>] [--operation-id <uuid>] [--require-pass]\n assethub evaluations list [--canvas <id>] [--artifact <asset-id>]\n assethub evaluations get <evaluation-id>\n assethub image generate --input-json <json|@file|@-> [--canvas <id>] [--operation-id <uuid>] [--agent <name>] [--derived-from-run <run-id>] [--from-node <graphId/nodeId> --graph-revision <rev>] [--wait]\n assethub mesh generate --input-json <json|@file|@-> [--canvas <id>] [--operation-id <uuid>] [--agent <name>] [--derived-from-run <run-id>] [--from-node <graphId/nodeId> --graph-revision <rev>] [--wait]\n assethub mesh generate --node <shape:id> --canvas <id> [--model-id <id>] [--params-json <json|@file>] [--operation-id <uuid>] [--wait]\n assethub mesh list [--query <text>] [--cursor <cursor>] [--limit <n>]\n assethub mesh get <mesh-asset-id>\n assethub mesh download <mesh-asset-id> --out-dir <directory>\n assethub image generate --prompt <text> [--file <path> | --source-url <url> | --stdin | --stdin-base64 | --stdin-data-uri | --stdin-json | --source-json <json|@file|@-> | --data-uri <uri> | --clipboard] [--file-name <name>] [--content-type <type>] [--model-id <id>] [--batch-size <n>] [--wait] [--download --out-dir <dir>] [--canvas <id>] [--operation-id <uuid>] [--api-version v2]\n assethub image generate --prompt <text> --source-resource-id <id> --api-version v2 [--model-id <id>] [--batch-size <n>] [--wait]\n assethub mesh generate (--file <path> | --source-url <url> | --source-resource-id <id> | --file-ref-json <json> | --stdin | --stdin-base64 | --stdin-data-uri | --stdin-json | --source-json <json|@file|@-> | --data-uri <uri>) [--file-name <name>] [--content-type <type>] [--model-id <id>] [--name <name>] [--wait] [--download --out-dir <dir>]\n assethub mesh retopo (--source-resource-id <id> | --source-url <url> | --file-ref-json <json> | --stdin | --stdin-base64 | --stdin-data-uri | --stdin-json | --source-json <json|@file|@-> | --data-uri <uri>) --model-id <id> [--file-name <name>] [--content-type <type>] [--wait] [--download --out-dir <dir>]\n assethub rig check (--file <path> | --source-url <url> | --source-resource-id <id> | --file-ref-json <json> | --stdin | --stdin-base64 | --stdin-data-uri | --stdin-json | --source-json <json|@file|@-> | --data-uri <uri>) [--name <name>] [--wait] [--download --out-dir <dir>]\n assethub rig create (--file <path> | --source-url <url> | --source-resource-id <id> | --file-ref-json <json> | --stdin | --stdin-base64 | --stdin-data-uri | --stdin-json | --source-json <json|@file|@-> | --data-uri <uri>) [--model v1.0-20240301|v2.5-20260210] [--rig-type biped|quadruped|hexapod|octopod|avian|serpentine|aquatic] [--spec tripo|mixamo] [--out-format glb|fbx] [--name <name>] [--wait] [--download --out-dir <dir>]\n assethub animate presets [--model v1.0-20240301|v2.5-20260210] [--rig-type <type>]\n assethub animate retarget --resource-id <id> --animation <preset-id> [--animation <preset-id>... up to 5 total] [--out-format glb|fbx] [--bake-animation true|false] [--export-with-geometry true|false] [--animate-in-place true|false] [--name <name>] [--wait] [--download --out-dir <dir>]\n assethub jobs get <job-id> [--download --out-dir <dir>]\n assethub jobs watch <job-id> [--interval-ms <ms>] [--timeout-ms <ms>] [--download --out-dir <dir>]\n assethub production analyze (--file <path> | --source-url <url> | --source-id <id> | --image-url <url> | --file-ref-json <json> | --stdin | --stdin-base64 | --stdin-data-uri | --stdin-json | --source-json <json|@file|@-> | --data-uri <uri> | --clipboard) [--file-name <name>] [--content-type <type>] [--part-extractor <name>] [--name <name>] [--skill-mode auto|manual|off] [--skill-id <id>...] [--context <canvas-id> --context-version <n>] [--wait] [--download --out-dir <dir>]\n assethub production agents\n assethub production automation --input-json <json|@file|@-> [--canvas <id>] [--operation-id <uuid>] [--wait]\n assethub production status <order-id> [--wait] [--download --out-dir <dir>]\n assethub production execute --order-id <id> --mission-id <id> --task-id <id> [--task-id <id>...] [--part-extractor <name>] [--part-extraction-mode fast|high_quality] [--wait] [--download --out-dir <dir>]\n assethub production run --order-id <id> --mission-id <id> [--run-mode full_auto|approval] [--task-id <id>...] [--part-extractor <name>] [--part-extraction-mode fast|high_quality] [--allowed-model-id <id>...] [--max-iterations <n>] [--max-cost-credits <n>] [--wait] [--download --out-dir <dir>]\n assethub production watch <order-id> [--interval-ms <ms>] [--timeout-ms <ms>] [--download --out-dir <dir>]\n assethub production intervene <order-id> (--exclude <target-id> | --include <target-id> | --add-part <name> | --rename <target-id>=<name> | --reject <target-id>[=<reason>] | --regenerate <target-id>=<mode> | --set-param <key>=<value> | --ops-json <json|@file|@->)... [--idempotency-key <key>]\n assethub production interventions <order-id>\n assethub runs upload <path> [--graph-id <id>] [--stream-id <id>] [--rev <n>] [--description <text>] [--tag <tag>...] [--skip-register] [--dry-run]\n assethub parts split (--file <path> | --source-url <url> | --source-id <id> | --image-url <url> | --file-ref-json <json> | --stdin | --stdin-base64 | --stdin-data-uri | --stdin-json | --source-json <json|@file|@-> | --data-uri <uri> | --clipboard | --order-id <id>) [--file-name <name>] [--content-type <type>] [--part-extractor <name>] [--skill-mode auto|manual|off] [--skill-id <id>...] [--wait] [--task-id <id>...] [--mission-id <id>] [--all-ready] [--download --out-dir <dir>]\n assethub parts compare (--file <path> | --source-url <url> | --source-id <id> | --image-url <url> | --file-ref-json <json> | --stdin | --stdin-base64 | --stdin-data-uri | --stdin-json | --source-json <json|@file|@-> | --data-uri <uri> | --clipboard) [--file-name <name>] [--content-type <type>] [--preprocess-prompt <text>] [--preprocess-model-id <id>] [--fail-on-preprocess-error] [--part-extractor <name>] [--wait] [--task-id <id>...] [--mission-id <id>] [--all-ready] [--download --out-dir <dir>]\n assethub autopilot [<image>] --demo [--yolo] [--json] [--max-regen <n>] [--stall-rounds <n>] [--tie-epsilon <x>] [--multiview 2-view|4-view|6-view] [--ab-mode serial|cross] [--credit-budget <n>]\n\nGlobal options:\n --api-key <key> Overrides saved auth and ASSETHUB_API_KEY.\n --base-url <url> Override the selected API origin. Default: https://app.assethub.io.\n --profile <name> Select this saved profile ahead of environment credentials and origin.\n --workspace <id> Select workspace scope for this command without changing saved selection.\n --config <path> Auth config path. Defaults to ~/.assethub/config.json.\n --version Show installed package version.\n --help Show help.\n\nExamples:\n ASSETHUB_API_KEY=ah_live_xxx assethub models list\n assethub auth login --api-key-stdin\n assethub models list --ids-only\n assethub files upload ./input.png --media-type image\n assethub source create --file ./input.png --media-type image\n pbpaste | assethub source create --stdin-data-uri --media-type image\n assethub source create --clipboard --media-type image --file-name clipboard.png\n printf '{\"image_url\":{\"url\":\"data:image/png;base64,...\"}}' | assethub parts split --stdin-json --part-extractor \"V1.5\" --wait\n base64 -i ./input.png | assethub parts split --stdin-base64 --file-name input.png --content-type image/png --part-extractor \"V1.5\" --wait\n cat ./input.png | assethub parts split --stdin --file-name input.png --part-extractor \"V1.5\" --wait\n assethub image generate --prompt \"stylized prop concept\" --wait\n assethub mesh generate --file ./input.png --wait\n assethub animate presets --rig-type biped\n assethub rig create --source-resource-id mesh_x --rig-type biped --wait\n assethub animate retarget --resource-id rig_x --animation preset:idle --wait\n assethub production analyze --file ./input.png --part-extractor \"V1.5\" --wait\n assethub production run --order-id ord_x --mission-id ms_x --run-mode full_auto --max-cost-credits 200 --wait\n assethub production watch ord_x\n assethub production intervene ord_x --exclude 7 --rename 3=\"left wing\" --idempotency-key review-2026-07-29\n assethub production interventions ord_x\n assethub runs upload ./out/pluffy-run-2026-07-30 --dry-run\n assethub runs upload ./out/pluffy-run-2026-07-30 --tag pluffy --description \"V3 humanoid, 18 parts\"\n assethub parts split --file ./input.png --part-extractor \"V1.5\" --wait --all-ready\n assethub parts compare --file ./input.png --preprocess-prompt \"clean white background, centered product photo\" --part-extractor \"V1.5\" --wait --all-ready\n";
|
|
25
|
+
export declare const usage = "AssetHub CLI\n\nCLI and MCP are available to all AssetHub users. Workspace permissions and feature availability apply.\n\nUsage:\n assethub --version\n assethub doctor [--mcp] [--profile <name>] [--timeout-ms <n>]\n assethub init [--agent claude-code|codex|cursor...] [--project] [--dry-run] [--base-url <url>] [--workspace <id>] [--profile <name>]\n assethub mcp tools [tool-name] [--account] [--profile <name>] [--timeout-ms <n>]\n assethub mcp config --client cursor|codex [--account] [--base-url <url>]\n assethub auth login --api-key <key> [--base-url <url>] [--profile <name>]\n assethub auth login --api-key-stdin [--base-url <url>] [--profile <name>]\n assethub auth login --access-token-stdin [--base-url <url>] [--profile <name>]\n assethub auth status [--profile <name>]\n assethub auth logout [--profile <name>]\n assethub workspace list [--query <text>] [--limit <1-100>] [--cursor <cursor>]\n assethub workspace get\n assethub workspace create --name <name> [--operation-id <uuid>]\n assethub workspace use <workspace-id>\n assethub workspace members [--workspace <id>]\n assethub workspace invite --email <email> [--role user|admin] [--resend] [--workspace <id>]\n assethub workspace set-role <user-id> --role user|admin [--workspace <id>]\n assethub workspace remove-member <user-id> [--workspace <id>]\n assethub workspace prepare|sync|analyze|verify --internal --manifest <json> --state <json>\n assethub workspace self-check --internal\n assethub workspace context put --internal --org <uuid> --actor <uuid> --canvas <id> --file <json> [--if-version <n>] [--order <uuid>]\n assethub workspace context get --internal --org <uuid> --actor <uuid> --canvas <id> [--out <json>] [--order <uuid>]\n assethub project ingest <source-dir> --out-dir <directory> [--exclude-dir <relative-path>...]\n assethub language text|vision --input-json @<json> --operation-id <uuid> [--out <json>]\n assethub canvas download --canvas <id> --out-dir <directory> [--mesh <mesh_asset_id>]\n assethub canvas nodes --canvas <id>\n assethub canvas import --canvas <id> --file <image> [--name <name>]\n assethub canvas context get --canvas <id> [--out <json>]\n assethub canvas context put --canvas <id> --file <json> [--if-version <n>]\n assethub canvas layout --canvas <id> --input-json @<json>\n assethub canvas compare --canvas <id> --source-id <asset-id> --asset-id <asset-id> --out <html>\n assethub moodboard create --input-json @<json> [--operation-id <uuid>]\n assethub moodboard list|get|update|archive [<board-id>] [--input-json @<json>]\n assethub moodboard analyze <board-id> [--revision <uuid>] [--wait]\n assethub image generate --canvas <id> --context <id> [--context-version <n>] [--context-source <key>] [--moodboard-revision <uuid>] --prompt <text> --wait\n assethub models list [--domain <domain>] [--ids-only] [--limit <n>]\n assethub models get <model-id>\n assethub files import <url> --media-type image|mesh\n assethub files upload <file> --media-type image|mesh\n assethub source create (--file <path> | --source-url <url> | --source-id <id> | --stdin | --stdin-base64 | --stdin-data-uri | --stdin-json | --source-json <json|@file|@-> | --data-uri <uri> | --clipboard) --media-type image|mesh [--file-name <name>] [--content-type <type>]\n assethub capabilities\n assethub api search [query]\n assethub api describe \"<METHOD /path>\"\n assethub api call \"<METHOD /path>\" [--path-json <json|@file>] [--query-json <json|@file>] [--input-json <json|@file|@->] [--operation-id <uuid>]\n assethub skills list [--cursor <cursor>]\n assethub skills get <skill-id> [--revision <n>]\n assethub skills learn --input-json <json|@file|@-> --operation-id <uuid>\n assethub skills update <skill-id> --input-json <json|@file|@->\n assethub skills controls <skill-id> --revision <n> --grant-revision <n> --mode automatic|manual|off [--share]\n assethub skills prepare --input-json <json|@file|@->\n assethub skills proposal <proposal-id>\n assethub skills accept <proposal-id> --input-json <json|@file|@->\n assethub composer models\n assethub composer refine --list-modes\n assethub composer refine --from-run <run-id> --instruction <text> [--mode standard|thorough|placement|workshop|blender|codex] [--max-rounds <n>] [--transforms-json <json|@file>] [--wait] [--download --out-dir <dir>]\n assethub composer refine --input-json <json|@file> [--canvas <id>] [--operation-id <uuid>] [--wait] [--download --out-dir <dir>]\n assethub composer run --part <mesh-asset-id>[:<part-image-asset-id>] [--part <mesh-asset-id>[:<part-image-asset-id>]...] --reference <image-asset-id> [--model <id>] [--mode quick|quality] [--transforms-json <json|@file>] [--canvas <id>] [--wait]\n assethub composer run --input-json <json|@file> [--canvas <id>] [--operation-id <uuid>] [--wait] [--download --out-dir <dir>]\n assethub composer run --from-run <run-id> [--transforms-json <json|@file>] [--mode quick|quality] [--wait]\n assethub composer run --node <shape:id> --canvas <id> [--model <id>] [--mode quick|quality] [--operation-id <uuid>] [--wait]\n assethub canvas create [--name <name>] [--operation-id <uuid>]\n assethub canvas list [--cursor <cursor>] [--limit <n>]\n assethub canvas get|use|open [<id>]\n assethub runs list [--canvas <id>] [--cursor <cursor>] [--limit <n>]\n assethub runs get|watch|wait <run-id> [--interval-ms <ms>] [--timeout-ms <n>] [--summary]\n assethub runs resume <operation-id> [--wait]\n assethub graph list [--cursor <cursor>] [--limit <n>]\n assethub graph show|export [--canvas <id> | --graph <id>] [--source generated|upload] [--artifact <node-id>] [--out <path>] [--allow-truncated]\n assethub graph lineage --artifact <node-id> [--canvas <id> | --graph <id>] [--source generated|upload] [--direction ancestors|descendants|both] [--depth <n>] [--out <path>]\n assethub evaluate list\n assethub evaluations submit --artifact <asset-id> --report <json|file|@file|@-> [--agent <name>] [--canvas <id>] [--reference <asset-id>...] [--run <run-id>] [--operation-id <uuid>] [--require-pass]\n assethub evaluations list [--canvas <id>] [--artifact <asset-id>]\n assethub evaluations get <evaluation-id>\n assethub image generate --input-json <json|@file|@-> [--canvas <id>] [--operation-id <uuid>] [--agent <name>] [--derived-from-run <run-id>] [--from-node <graphId/nodeId> --graph-revision <rev>] [--wait]\n assethub mesh generate --input-json <json|@file|@-> [--canvas <id>] [--operation-id <uuid>] [--agent <name>] [--derived-from-run <run-id>] [--from-node <graphId/nodeId> --graph-revision <rev>] [--wait]\n assethub mesh generate --node <shape:id> --canvas <id> [--model-id <id>] [--params-json <json|@file>] [--operation-id <uuid>] [--wait]\n assethub mesh list [--query <text>] [--cursor <cursor>] [--limit <n>]\n assethub mesh get <mesh-asset-id>\n assethub mesh download <mesh-asset-id> --out-dir <directory>\n assethub image generate --prompt <text> [--file <path> | --source-url <url> | --stdin | --stdin-base64 | --stdin-data-uri | --stdin-json | --source-json <json|@file|@-> | --data-uri <uri> | --clipboard] [--file-name <name>] [--content-type <type>] [--model-id <id>] [--batch-size <n>] [--wait] [--download --out-dir <dir>] [--canvas <id>] [--operation-id <uuid>] [--api-version v2]\n assethub image generate --prompt <text> --source-resource-id <id> --api-version v2 [--model-id <id>] [--batch-size <n>] [--wait]\n assethub mesh generate (--file <path> | --source-url <url> | --source-resource-id <id> | --file-ref-json <json> | --stdin | --stdin-base64 | --stdin-data-uri | --stdin-json | --source-json <json|@file|@-> | --data-uri <uri>) [--file-name <name>] [--content-type <type>] [--model-id <id>] [--name <name>] [--wait] [--download --out-dir <dir>]\n assethub mesh retopo (--source-resource-id <id> | --source-url <url> | --file-ref-json <json> | --stdin | --stdin-base64 | --stdin-data-uri | --stdin-json | --source-json <json|@file|@-> | --data-uri <uri>) --model-id <id> [--file-name <name>] [--content-type <type>] [--wait] [--download --out-dir <dir>]\n assethub rig check (--file <path> | --source-url <url> | --source-resource-id <id> | --file-ref-json <json> | --stdin | --stdin-base64 | --stdin-data-uri | --stdin-json | --source-json <json|@file|@-> | --data-uri <uri>) [--name <name>] [--wait] [--download --out-dir <dir>]\n assethub rig create (--file <path> | --source-url <url> | --source-resource-id <id> | --file-ref-json <json> | --stdin | --stdin-base64 | --stdin-data-uri | --stdin-json | --source-json <json|@file|@-> | --data-uri <uri>) [--model v1.0-20240301|v2.5-20260210] [--rig-type biped|quadruped|hexapod|octopod|avian|serpentine|aquatic] [--spec tripo|mixamo] [--out-format glb|fbx] [--name <name>] [--wait] [--download --out-dir <dir>]\n assethub animate presets [--model v1.0-20240301|v2.5-20260210] [--rig-type <type>]\n assethub animate retarget --resource-id <id> --animation <preset-id> [--animation <preset-id>... up to 5 total] [--out-format glb|fbx] [--bake-animation true|false] [--export-with-geometry true|false] [--animate-in-place true|false] [--name <name>] [--wait] [--download --out-dir <dir>]\n assethub jobs get <job-id> [--download --out-dir <dir>]\n assethub jobs watch <job-id> [--interval-ms <ms>] [--timeout-ms <ms>] [--download --out-dir <dir>]\n assethub production analyze (--file <path> | --source-url <url> | --source-id <id> | --image-url <url> | --file-ref-json <json> | --stdin | --stdin-base64 | --stdin-data-uri | --stdin-json | --source-json <json|@file|@-> | --data-uri <uri> | --clipboard) [--file-name <name>] [--content-type <type>] [--part-extractor <name>] [--name <name>] [--skill-mode auto|manual|off] [--skill-id <id>...] [--context <canvas-id> --context-version <n>] [--wait] [--download --out-dir <dir>]\n assethub production agents\n assethub production automation --input-json <json|@file|@-> [--canvas <id>] [--operation-id <uuid>] [--wait]\n assethub production status <order-id> [--wait] [--download --out-dir <dir>]\n assethub production execute --order-id <id> --mission-id <id> --task-id <id> [--task-id <id>...] [--part-extractor <name>] [--part-extraction-mode fast|high_quality] [--wait] [--download --out-dir <dir>]\n assethub production run --order-id <id> --mission-id <id> [--run-mode full_auto|approval] [--task-id <id>...] [--part-extractor <name>] [--part-extraction-mode fast|high_quality] [--allowed-model-id <id>...] [--max-iterations <n>] [--max-cost-credits <n>] [--wait] [--download --out-dir <dir>]\n assethub production run --image <file|asset-id> [--canvas <id>] [--part-extractor <name>] [--compose v6|none] [--mesh-model <id>] [--max-parts <n>] [--max-cost <credits>] [--estimate] [--wait] [--download --out-dir <dir>] [--json]\n assethub production watch <order-id> [--interval-ms <ms>] [--timeout-ms <ms>] [--download --out-dir <dir>]\n assethub production intervene <order-id> (--exclude <target-id> | --include <target-id> | --add-part <name> | --rename <target-id>=<name> | --reject <target-id>[=<reason>] | --regenerate <target-id>=<mode> | --set-param <key>=<value> | --ops-json <json|@file|@->)... [--idempotency-key <key>]\n assethub production interventions <order-id>\n assethub runs upload <path> [--graph-id <id>] [--stream-id <id>] [--rev <n>] [--description <text>] [--tag <tag>...] [--skip-register] [--dry-run]\n assethub parts split (--file <path> | --source-url <url> | --source-id <id> | --image-url <url> | --file-ref-json <json> | --stdin | --stdin-base64 | --stdin-data-uri | --stdin-json | --source-json <json|@file|@-> | --data-uri <uri> | --clipboard | --order-id <id>) [--file-name <name>] [--content-type <type>] [--part-extractor <name>] [--skill-mode auto|manual|off] [--skill-id <id>...] [--wait] [--task-id <id>...] [--mission-id <id>] [--all-ready] [--download --out-dir <dir>]\n assethub parts compare (--file <path> | --source-url <url> | --source-id <id> | --image-url <url> | --file-ref-json <json> | --stdin | --stdin-base64 | --stdin-data-uri | --stdin-json | --source-json <json|@file|@-> | --data-uri <uri> | --clipboard) [--file-name <name>] [--content-type <type>] [--preprocess-prompt <text>] [--preprocess-model-id <id>] [--fail-on-preprocess-error] [--part-extractor <name>] [--wait] [--task-id <id>...] [--mission-id <id>] [--all-ready] [--download --out-dir <dir>]\n assethub autopilot [<image>] --demo [--yolo] [--json] [--max-regen <n>] [--stall-rounds <n>] [--tie-epsilon <x>] [--multiview 2-view|4-view|6-view] [--ab-mode serial|cross] [--credit-budget <n>]\n\nGlobal options:\n --api-key <key> Overrides saved auth and ASSETHUB_API_KEY.\n --base-url <url> Override the selected API origin. Default: https://app.assethub.io.\n --profile <name> Select this saved profile ahead of environment credentials and origin.\n --workspace <id> Select workspace scope for this command without changing saved selection.\n --config <path> Auth config path. Defaults to ~/.assethub/config.json.\n --version Show installed package version.\n --help Show help.\n\nExamples:\n ASSETHUB_API_KEY=ah_live_xxx assethub models list\n assethub auth login --api-key-stdin\n assethub init --dry-run\n assethub models list --ids-only\n assethub files upload ./input.png --media-type image\n assethub source create --file ./input.png --media-type image\n pbpaste | assethub source create --stdin-data-uri --media-type image\n assethub source create --clipboard --media-type image --file-name clipboard.png\n printf '{\"image_url\":{\"url\":\"data:image/png;base64,...\"}}' | assethub parts split --stdin-json --part-extractor \"V1.5\" --wait\n base64 -i ./input.png | assethub parts split --stdin-base64 --file-name input.png --content-type image/png --part-extractor \"V1.5\" --wait\n cat ./input.png | assethub parts split --stdin --file-name input.png --part-extractor \"V1.5\" --wait\n assethub image generate --prompt \"stylized prop concept\" --wait\n assethub mesh generate --file ./input.png --wait\n assethub animate presets --rig-type biped\n assethub rig create --source-resource-id mesh_x --rig-type biped --wait\n assethub animate retarget --resource-id rig_x --animation preset:idle --wait\n assethub production analyze --file ./input.png --part-extractor \"V1.5\" --wait\n assethub production run --order-id ord_x --mission-id ms_x --run-mode full_auto --max-cost-credits 200 --wait\n assethub production run --image ./character.png --estimate\n assethub production run --image ./character.png --compose v6 --max-cost 500 --wait --download --out-dir ./out/asset\n assethub production watch ord_x\n assethub runs get run_x --summary\n assethub runs wait run_x --timeout-ms 3600000\n assethub production intervene ord_x --exclude 7 --rename 3=\"left wing\" --idempotency-key review-2026-07-29\n assethub production interventions ord_x\n assethub runs upload ./out/pluffy-run-2026-07-30 --dry-run\n assethub runs upload ./out/pluffy-run-2026-07-30 --tag pluffy --description \"V3 humanoid, 18 parts\"\n assethub parts split --file ./input.png --part-extractor \"V1.5\" --wait --all-ready\n assethub parts compare --file ./input.png --preprocess-prompt \"clean white background, centered product photo\" --part-extractor \"V1.5\" --wait --all-ready\n";
|
|
26
26
|
export declare const commandSkills: (subcommand: string | undefined, positionals: string[], ctx: CommandContext) => Promise<void>;
|
|
27
27
|
/**
|
|
28
28
|
* The `animate retarget` request, built from flags alone.
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AA6BA,OAAO,EAQL,KAAK,wBAAwB,EAO7B,KAAK,YAAY,EAEjB,KAAK,UAAU,EAkBf,oBAAoB,EACrB,MAAM,sBAAsB,CAAA;AAc7B,OAAO,EAAC,kBAAkB,EAAc,MAAM,gCAAgC,CAAA;AAoB9E,KAAK,KAAK,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,GAAG,MAAM,EAAE,CAAC,CAAA;AAuBxD,KAAK,YAAY,GAAG;IAClB,MAAM,EAAE,MAAM,CAAA;IACd,cAAc,CAAC,EAAE,UAAU,CAAA;IAC3B,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,OAAO,EAAE,MAAM,CAAA;IACf,OAAO,EAAE,MAAM,CAAA;IACf,MAAM,EAAE,MAAM,GAAG,KAAK,GAAG,SAAS,CAAA;CACnC,CAAA;AAED,KAAK,cAAc,GAAG;IACpB,MAAM,EAAE,UAAU,CAAC,OAAO,oBAAoB,CAAC,CAAA;IAC/C,KAAK,EAAE,KAAK,CAAA;IACZ,IAAI,EAAE,YAAY,CAAA;IAClB;;;;;OAKG;IACH,IAAI,EAAE,MAAM,EAAE,CAAA;CACf,CAAA;AA4ID,eAAO,MAAM,KAAK,s+dAoJjB,CAAA;AA2gDD,eAAO,MAAM,aAAa,GACxB,YAAY,MAAM,GAAG,SAAS,EAC9B,aAAa,MAAM,EAAE,EACrB,KAAK,cAAc,KAClB,OAAO,CAAC,IAAI,CA6Hd,CAAA;AA61CD;;;;;;GAMG;AACH,eAAO,MAAM,6BAA6B,GACxC,OAAO,KAAK,KACX,wBA0BF,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,qBAAqB,GAChC,OAAO,KAAK,KACX,IAAI,CAAC,UAAU,EAAE,QAAQ,CAM1B,CAAA;AA6fF;;;;;;;;;;;;;;;;;;GAkBG;AACH,eAAO,MAAM,uBAAuB,GAClC,MAAM,SAAS,MAAM,EAAE,KACtB,YAAY,EAuGd,CAAA;AAy7CD,MAAM,MAAM,cAAc,GAAG;IAC3B,UAAU,EAAE,MAAM,CAAA;IAClB,OAAO,EAAE,MAAM,GAAG,SAAS,CAAA;IAC3B,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAA;IAC5B,GAAG,EAAE,MAAM,GAAG,SAAS,CAAA;IACvB,WAAW,EAAE,MAAM,CAAA;IACnB,IAAI,EAAE,MAAM,EAAE,CAAA;IACd,MAAM,EAAE,OAAO,CAAA;IACf,YAAY,EAAE,OAAO,CAAA;CACtB,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,GAC9B,YAAY,MAAM,GAAG,SAAS,EAC9B,aAAa,MAAM,EAAE,EACrB,OAAO,KAAK,KACX,cAoBF,CAAA;AAED,KAAK,iBAAiB,GAAG,IAAI,CAC3B,OAAO,CAAC,UAAU,CAAC,OAAO,kBAAkB,CAAC,CAAC,EAC5C,SAAS,GACT,UAAU,GACV,KAAK,GACL,WAAW,GACX,QAAQ,GACR,OAAO,GACP,OAAO,GACP,UAAU,CACb,CAAA;AAED,eAAO,MAAM,iBAAiB,GAC5B,WAAW,MAAM,EACjB,MAAM,iBAAiB;;;;;;;;;;;;;;CAUvB,CAAA;AAEF,eAAO,MAAM,sBAAsB,GACjC,SAAS,UAAU,CAAC,OAAO,iBAAiB,CAAC,EAC7C,MAAM,iBAAiB,EACvB,SAAS,MAAM;;;;;;;;;;;;;;;;;;;;;;;CAYf,CAAA"}
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { setTimeout as delay } from 'node:timers/promises';
|
|
3
3
|
import { cliVersion, diagnose, mcpConfig } from './setup.js';
|
|
4
|
+
import { AGENT_IDS, initAgents, syncInstalledSkill } from './agentSetup.js';
|
|
4
5
|
import { ingestProjectSources } from './projectSources.js';
|
|
5
6
|
import { downloadCanvas } from './canvasDownload.js';
|
|
6
7
|
import { executeNodeMeshBatch, resumeNodeMeshBatch, } from './nodeMeshBatch.js';
|
|
@@ -21,6 +22,8 @@ import { activeExecution, childOperationId, CliExecutionError, executeRecorded,
|
|
|
21
22
|
import { buildRunUploadPlan, formatBytes } from './runsUpload/buildRunUpload.js';
|
|
22
23
|
import { readGraphFolder } from './runsUpload/graphFolder.js';
|
|
23
24
|
import { uploadRun } from './runsUpload/uploadRun.js';
|
|
25
|
+
import { existsSync } from 'node:fs';
|
|
26
|
+
import { DEFAULT_MAX_PARTS, buildAutomationConfig, buildComposerPartsFromMeshExecutions, detectOneShotImageInput, estimateOneShotCost, exceedsMaxCost, formatExecutionSummaryLines, parseComposeFlag, pollAutomationBatch, readServerCostBreakdown, resolveFullBodyImageAssetId, serverSupportsV6Compose, withErrorHint, } from './productionOneShot.js';
|
|
24
27
|
const defaultBaseUrl = 'https://app.assethub.io';
|
|
25
28
|
// Mirrors PUBLIC_IMAGE_GENERATE_DEFAULT_MODEL_ID in apps/frontend
|
|
26
29
|
// (src/feature/imageGen/util/publicImageGenDefaultModel.ts). This package does
|
|
@@ -30,15 +33,6 @@ const defaultImageModelId = 'imageGen.nanoBanana2.openrouter';
|
|
|
30
33
|
const defaultMeshModelId = 'meshGen.hunyuan31';
|
|
31
34
|
const defaultProfileName = 'default';
|
|
32
35
|
const defaultPartExtractorName = 'V1.5';
|
|
33
|
-
const artifactGraphPartExtractorApiValues = new Set([
|
|
34
|
-
'ah_agent_graph_v3_6_1',
|
|
35
|
-
'ah_agent_graph_v3_6_3',
|
|
36
|
-
'ah_agent_graph_v3_6_4',
|
|
37
|
-
'ah_agent_graph_v3_6_5',
|
|
38
|
-
'ah_agent_graph_pluffy_v3_1',
|
|
39
|
-
'ah_agent_graph_v3_7',
|
|
40
|
-
'ah_agent_graph_v3_7_1',
|
|
41
|
-
]);
|
|
42
36
|
const partExtractorOptions = [
|
|
43
37
|
{
|
|
44
38
|
publicName: 'V1.5',
|
|
@@ -80,17 +74,34 @@ const partExtractorOptions = [
|
|
|
80
74
|
apiValue: 'ah_agent_graph_pluffy_v3_1',
|
|
81
75
|
aliases: ['pluffy', 'pluffy v3.1', 'pluffy 3.1'],
|
|
82
76
|
},
|
|
77
|
+
{
|
|
78
|
+
publicName: 'V3.0.9 Garment Boundaries',
|
|
79
|
+
apiValue: 'ah_agent_graph_v3_7_2',
|
|
80
|
+
aliases: ['v3.0.9', '3.0.9'],
|
|
81
|
+
},
|
|
83
82
|
{
|
|
84
83
|
publicName: 'V3.7 Artist Skills',
|
|
85
84
|
apiValue: 'ah_agent_graph_v3_7',
|
|
86
|
-
|
|
85
|
+
// The web picker and `production agents` call it V3.0.7.
|
|
86
|
+
aliases: ['v3.7', '3.7', 'v3.0.7 artist skills', 'v3.0.7', '3.0.7'],
|
|
87
87
|
},
|
|
88
88
|
{
|
|
89
89
|
publicName: 'V3.7.1 Building Modules',
|
|
90
90
|
apiValue: 'ah_agent_graph_v3_7_1',
|
|
91
|
-
|
|
91
|
+
// The web picker and `production agents` call it V3.0.8.
|
|
92
|
+
aliases: ['v3.7.1', '3.7.1', 'v3.0.8 building modules', 'v3.0.8', '3.0.8'],
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
publicName: 'Humanoid Assembly (internal)',
|
|
96
|
+
apiValue: 'ah_agent_graph_humanoid_assembly_auto',
|
|
97
|
+
aliases: ['humanoid assembly', 'humanoid-assembly', 'humanoid_assembly_auto'],
|
|
92
98
|
},
|
|
93
99
|
];
|
|
100
|
+
// Graph-engine extractors run through the artifact-graph endpoint. Derived from
|
|
101
|
+
// the option list so a newly listed graph agent cannot miss the graph path.
|
|
102
|
+
const artifactGraphPartExtractorApiValues = new Set(partExtractorOptions
|
|
103
|
+
.map(option => option.apiValue)
|
|
104
|
+
.filter(apiValue => apiValue.startsWith('ah_agent_graph_')));
|
|
94
105
|
const partExtractorPublicNames = partExtractorOptions
|
|
95
106
|
.map(option => option.publicName)
|
|
96
107
|
.join(', ');
|
|
@@ -100,7 +111,12 @@ const partExtractorByInput = new Map(partExtractorOptions.flatMap(option => [
|
|
|
100
111
|
...option.aliases.map(alias => [normalizePartExtractorName(alias), option]),
|
|
101
112
|
]));
|
|
102
113
|
const partExtractorPublicNameByApiValue = new Map(partExtractorOptions.map(option => [option.apiValue, option.publicName]));
|
|
103
|
-
|
|
114
|
+
// Every registered internal apiValue is an `ah_...` id (see partExtractorOptions
|
|
115
|
+
// above). Matching that prefix instead of a blanket "contains an underscore"
|
|
116
|
+
// check keeps this from rejecting a public alias that happens to use
|
|
117
|
+
// underscores (e.g. 'humanoid_assembly_auto', mirroring the engine profile
|
|
118
|
+
// name) while still catching every real internal id.
|
|
119
|
+
const isInternalPartExtractorId = (value) => value.trim().toLowerCase().startsWith('ah_');
|
|
104
120
|
const execFileAsync = promisify(execFile);
|
|
105
121
|
export const usage = `AssetHub CLI
|
|
106
122
|
|
|
@@ -109,6 +125,7 @@ CLI and MCP are available to all AssetHub users. Workspace permissions and featu
|
|
|
109
125
|
Usage:
|
|
110
126
|
assethub --version
|
|
111
127
|
assethub doctor [--mcp] [--profile <name>] [--timeout-ms <n>]
|
|
128
|
+
assethub init [--agent claude-code|codex|cursor...] [--project] [--dry-run] [--base-url <url>] [--workspace <id>] [--profile <name>]
|
|
112
129
|
assethub mcp tools [tool-name] [--account] [--profile <name>] [--timeout-ms <n>]
|
|
113
130
|
assethub mcp config --client cursor|codex [--account] [--base-url <url>]
|
|
114
131
|
assethub auth login --api-key <key> [--base-url <url>] [--profile <name>]
|
|
@@ -162,7 +179,7 @@ Usage:
|
|
|
162
179
|
assethub composer refine --list-modes
|
|
163
180
|
assethub composer refine --from-run <run-id> --instruction <text> [--mode standard|thorough|placement|workshop|blender|codex] [--max-rounds <n>] [--transforms-json <json|@file>] [--wait] [--download --out-dir <dir>]
|
|
164
181
|
assethub composer refine --input-json <json|@file> [--canvas <id>] [--operation-id <uuid>] [--wait] [--download --out-dir <dir>]
|
|
165
|
-
assethub composer run --part <mesh-asset-id> [--part <mesh-asset-id
|
|
182
|
+
assethub composer run --part <mesh-asset-id>[:<part-image-asset-id>] [--part <mesh-asset-id>[:<part-image-asset-id>]...] --reference <image-asset-id> [--model <id>] [--mode quick|quality] [--transforms-json <json|@file>] [--canvas <id>] [--wait]
|
|
166
183
|
assethub composer run --input-json <json|@file> [--canvas <id>] [--operation-id <uuid>] [--wait] [--download --out-dir <dir>]
|
|
167
184
|
assethub composer run --from-run <run-id> [--transforms-json <json|@file>] [--mode quick|quality] [--wait]
|
|
168
185
|
assethub composer run --node <shape:id> --canvas <id> [--model <id>] [--mode quick|quality] [--operation-id <uuid>] [--wait]
|
|
@@ -170,7 +187,7 @@ Usage:
|
|
|
170
187
|
assethub canvas list [--cursor <cursor>] [--limit <n>]
|
|
171
188
|
assethub canvas get|use|open [<id>]
|
|
172
189
|
assethub runs list [--canvas <id>] [--cursor <cursor>] [--limit <n>]
|
|
173
|
-
assethub runs get|watch <run-id> [--timeout-ms <n>]
|
|
190
|
+
assethub runs get|watch|wait <run-id> [--interval-ms <ms>] [--timeout-ms <n>] [--summary]
|
|
174
191
|
assethub runs resume <operation-id> [--wait]
|
|
175
192
|
assethub graph list [--cursor <cursor>] [--limit <n>]
|
|
176
193
|
assethub graph show|export [--canvas <id> | --graph <id>] [--source generated|upload] [--artifact <node-id>] [--out <path>] [--allow-truncated]
|
|
@@ -201,6 +218,7 @@ Usage:
|
|
|
201
218
|
assethub production status <order-id> [--wait] [--download --out-dir <dir>]
|
|
202
219
|
assethub production execute --order-id <id> --mission-id <id> --task-id <id> [--task-id <id>...] [--part-extractor <name>] [--part-extraction-mode fast|high_quality] [--wait] [--download --out-dir <dir>]
|
|
203
220
|
assethub production run --order-id <id> --mission-id <id> [--run-mode full_auto|approval] [--task-id <id>...] [--part-extractor <name>] [--part-extraction-mode fast|high_quality] [--allowed-model-id <id>...] [--max-iterations <n>] [--max-cost-credits <n>] [--wait] [--download --out-dir <dir>]
|
|
221
|
+
assethub production run --image <file|asset-id> [--canvas <id>] [--part-extractor <name>] [--compose v6|none] [--mesh-model <id>] [--max-parts <n>] [--max-cost <credits>] [--estimate] [--wait] [--download --out-dir <dir>] [--json]
|
|
204
222
|
assethub production watch <order-id> [--interval-ms <ms>] [--timeout-ms <ms>] [--download --out-dir <dir>]
|
|
205
223
|
assethub production intervene <order-id> (--exclude <target-id> | --include <target-id> | --add-part <name> | --rename <target-id>=<name> | --reject <target-id>[=<reason>] | --regenerate <target-id>=<mode> | --set-param <key>=<value> | --ops-json <json|@file|@->)... [--idempotency-key <key>]
|
|
206
224
|
assethub production interventions <order-id>
|
|
@@ -221,6 +239,7 @@ Global options:
|
|
|
221
239
|
Examples:
|
|
222
240
|
ASSETHUB_API_KEY=ah_live_xxx assethub models list
|
|
223
241
|
assethub auth login --api-key-stdin
|
|
242
|
+
assethub init --dry-run
|
|
224
243
|
assethub models list --ids-only
|
|
225
244
|
assethub files upload ./input.png --media-type image
|
|
226
245
|
assethub source create --file ./input.png --media-type image
|
|
@@ -236,7 +255,11 @@ Examples:
|
|
|
236
255
|
assethub animate retarget --resource-id rig_x --animation preset:idle --wait
|
|
237
256
|
assethub production analyze --file ./input.png --part-extractor "V1.5" --wait
|
|
238
257
|
assethub production run --order-id ord_x --mission-id ms_x --run-mode full_auto --max-cost-credits 200 --wait
|
|
258
|
+
assethub production run --image ./character.png --estimate
|
|
259
|
+
assethub production run --image ./character.png --compose v6 --max-cost 500 --wait --download --out-dir ./out/asset
|
|
239
260
|
assethub production watch ord_x
|
|
261
|
+
assethub runs get run_x --summary
|
|
262
|
+
assethub runs wait run_x --timeout-ms 3600000
|
|
240
263
|
assethub production intervene ord_x --exclude 7 --rename 3="left wing" --idempotency-key review-2026-07-29
|
|
241
264
|
assethub production interventions ord_x
|
|
242
265
|
assethub runs upload ./out/pluffy-run-2026-07-30 --dry-run
|
|
@@ -728,6 +751,25 @@ const assertFlagHasValue = (value, flagDescription) => {
|
|
|
728
751
|
}
|
|
729
752
|
return value;
|
|
730
753
|
};
|
|
754
|
+
/**
|
|
755
|
+
* Parses one `--part` value for `composer run`/`composer refine` into a
|
|
756
|
+
* composer part. Plain `<mesh-asset-id>` composes without a part-reference
|
|
757
|
+
* image (Composer V6 then requires it via `--input-json` or falls back to
|
|
758
|
+
* the mesh's own thumbnail, if enabled). `<mesh-asset-id>:<part-image-asset-id>`
|
|
759
|
+
* attaches the image the part's mesh was generated from, matching what the
|
|
760
|
+
* canvas node graph supplies automatically for UI-driven runs.
|
|
761
|
+
*/
|
|
762
|
+
const parsePartFlagValue = (raw) => {
|
|
763
|
+
const value = assertFlagHasValue(raw, '--part <mesh-asset-id>[:<part-image-asset-id>]');
|
|
764
|
+
const separatorIndex = value.indexOf(':');
|
|
765
|
+
if (separatorIndex === -1)
|
|
766
|
+
return { assetId: value };
|
|
767
|
+
const assetId = value.slice(0, separatorIndex);
|
|
768
|
+
const partImageAssetId = value.slice(separatorIndex + 1);
|
|
769
|
+
if (!assetId || !partImageAssetId)
|
|
770
|
+
throw new Error('--part must be <mesh-asset-id> or <mesh-asset-id>:<part-image-asset-id>');
|
|
771
|
+
return { assetId, partImageAssetId };
|
|
772
|
+
};
|
|
731
773
|
const sourceInputCount = (flags) => [
|
|
732
774
|
getSourceResourceIdFlag(flags) != null,
|
|
733
775
|
getSourceUrlFlag(flags) != null,
|
|
@@ -2243,9 +2285,7 @@ const commandComposerRefine = async (ctx) => {
|
|
|
2243
2285
|
: previous
|
|
2244
2286
|
? composerInputFromRun(previous, 'mesh.refine')
|
|
2245
2287
|
: {
|
|
2246
|
-
parts: parts.map(
|
|
2247
|
-
assetId: assertFlagHasValue(assetId, '--part <asset-id>'),
|
|
2248
|
-
})),
|
|
2288
|
+
parts: parts.map(parsePartFlagValue),
|
|
2249
2289
|
fullBodyImageAssetId: requireFlag(ctx.flags, 'reference'),
|
|
2250
2290
|
};
|
|
2251
2291
|
delete input.executionContext;
|
|
@@ -2354,9 +2394,7 @@ const commandComposer = async (subcommand, ctx) => {
|
|
|
2354
2394
|
: json
|
|
2355
2395
|
? await readJsonArgument(json, '--input-json')
|
|
2356
2396
|
: {
|
|
2357
|
-
parts: parts.map(
|
|
2358
|
-
assetId: assertFlagHasValue(assetId, '--part <asset-id>'),
|
|
2359
|
-
})),
|
|
2397
|
+
parts: parts.map(parsePartFlagValue),
|
|
2360
2398
|
fullBodyImageAssetId: requireFlag(ctx.flags, 'reference'),
|
|
2361
2399
|
};
|
|
2362
2400
|
delete input.executionContext;
|
|
@@ -3079,6 +3117,155 @@ const productionSession = (ctx, operation, canvasId = selectedCanvasId(ctx.flags
|
|
|
3079
3117
|
canvasId,
|
|
3080
3118
|
operation,
|
|
3081
3119
|
});
|
|
3120
|
+
/**
|
|
3121
|
+
* `production run --image <file|assetId>`: the one-shot "image -> finished
|
|
3122
|
+
* asset" command. A thin wrapper around `production automation` (which
|
|
3123
|
+
* already does split -> mesh x N -> compose server-side) plus waiting,
|
|
3124
|
+
* cost estimation and downloads — it never re-implements the manual
|
|
3125
|
+
* split/mesh/compose dance. See productionOneShot.ts for the pure,
|
|
3126
|
+
* independently-tested pieces (image-flag resolution, cost estimate math,
|
|
3127
|
+
* batch-status polling, the V6 compose fallback's mesh<->image pairing, and
|
|
3128
|
+
* error hints); this function only wires them to the client and to flags.
|
|
3129
|
+
*/
|
|
3130
|
+
const commandProductionRunOneShot = async (ctx) => {
|
|
3131
|
+
if (sourceInputCount(ctx.flags) > 0) {
|
|
3132
|
+
throw new Error('--image already resolves a source; do not combine it with --file/--source-id/--source-url/other source flags.');
|
|
3133
|
+
}
|
|
3134
|
+
const imageValue = requireFlag(ctx.flags, 'image');
|
|
3135
|
+
const detected = detectOneShotImageInput(imageValue, existsSync);
|
|
3136
|
+
const sourceFlags = {
|
|
3137
|
+
...ctx.flags,
|
|
3138
|
+
...(detected.kind === 'file'
|
|
3139
|
+
? { file: detected.path }
|
|
3140
|
+
: { 'source-id': detected.resourceId }),
|
|
3141
|
+
};
|
|
3142
|
+
const compose = parseComposeFlag(getFlag(ctx.flags, 'compose'));
|
|
3143
|
+
const meshModelId = getFlag(ctx.flags, 'mesh-model') ?? defaultMeshModelId;
|
|
3144
|
+
const maxParts = getFlag(ctx.flags, 'max-parts') == null
|
|
3145
|
+
? DEFAULT_MAX_PARTS
|
|
3146
|
+
: parsePositiveIntegerFlag(ctx.flags, 'max-parts', 1);
|
|
3147
|
+
const maxCostCredits = getFlag(ctx.flags, 'max-cost') == null
|
|
3148
|
+
? undefined
|
|
3149
|
+
: parsePositiveIntegerFlag(ctx.flags, 'max-cost', 1);
|
|
3150
|
+
const agentVersion = resolvePartExtractorForAnalyze(ctx.flags);
|
|
3151
|
+
// Every number below comes from a side-effect-free GET; nothing here
|
|
3152
|
+
// starts real (billable) work, so this runs whether or not --estimate was
|
|
3153
|
+
// passed and gates --max-cost before the real automation call below.
|
|
3154
|
+
const [models, composerCapabilities] = await Promise.all([
|
|
3155
|
+
ctx.client.v2.listModels({ domain: 'meshGen' }),
|
|
3156
|
+
ctx.client.v2.getMeshComposers(),
|
|
3157
|
+
]);
|
|
3158
|
+
const meshModel = models.find(model => model.id === meshModelId);
|
|
3159
|
+
const composeCredits = compose === 'v6'
|
|
3160
|
+
? (composerCapabilities.quotes?.find(quote => quote.agentVersion === 'v6')
|
|
3161
|
+
?.credits ?? null)
|
|
3162
|
+
: undefined;
|
|
3163
|
+
const estimate = estimateOneShotCost({
|
|
3164
|
+
meshModel,
|
|
3165
|
+
maxParts,
|
|
3166
|
+
composeRequested: compose === 'v6',
|
|
3167
|
+
composeCredits,
|
|
3168
|
+
});
|
|
3169
|
+
if (exceedsMaxCost(estimate.totalCredits, maxCostCredits)) {
|
|
3170
|
+
throw new Error(`Estimated cost ${estimate.totalCredits} credits exceeds --max-cost ${maxCostCredits}; refusing to run before spending anything. ${estimate.notes.join(' ')}`);
|
|
3171
|
+
}
|
|
3172
|
+
if (hasFlag(ctx.flags, 'estimate')) {
|
|
3173
|
+
print({ estimate });
|
|
3174
|
+
return;
|
|
3175
|
+
}
|
|
3176
|
+
const session = await productionSession(ctx, 'production.automation');
|
|
3177
|
+
const source = await recordedSource(ctx, await requireSource({
|
|
3178
|
+
flags: sourceFlags,
|
|
3179
|
+
client: ctx.client,
|
|
3180
|
+
fileMediaType: 'image',
|
|
3181
|
+
preferUploadId: true,
|
|
3182
|
+
}));
|
|
3183
|
+
const analyzeImage = productionAnalyzeSourceFromSource(source);
|
|
3184
|
+
const config = buildAutomationConfig(compose);
|
|
3185
|
+
const body = {
|
|
3186
|
+
images: [analyzeImage],
|
|
3187
|
+
agentVersion,
|
|
3188
|
+
...(config ? { config } : {}),
|
|
3189
|
+
...(maxCostCredits != null ? { maxCostCredits } : {}),
|
|
3190
|
+
};
|
|
3191
|
+
const queued = (await executeRecorded(session, 'production.automation', body, executionOptions(ctx.flags)));
|
|
3192
|
+
stderr.write(`[run] batch=${queued.batchId}\n`);
|
|
3193
|
+
// `estimatedCostBreakdown`'s presence on the automation response itself
|
|
3194
|
+
// (assethub-web #8179) is the proof that this server understood
|
|
3195
|
+
// `partComposerAgentVersion` and already ran Composer V6 server-side, in
|
|
3196
|
+
// the same call — no client-side fallback compose is needed. Its absence
|
|
3197
|
+
// means an older, currently-deployed server silently ignored that field,
|
|
3198
|
+
// so the CLI still has to pair parts and run compose itself below.
|
|
3199
|
+
const serverHandledV6Compose = compose === 'v6' &&
|
|
3200
|
+
serverSupportsV6Compose(queued);
|
|
3201
|
+
const needsFallbackCompose = compose === 'v6' && !serverHandledV6Compose;
|
|
3202
|
+
let batchStatus;
|
|
3203
|
+
if (hasFlag(ctx.flags, 'wait') || needsFallbackCompose) {
|
|
3204
|
+
batchStatus = await pollAutomationBatch({
|
|
3205
|
+
getStatus: () => ctx.client.v1.getProductionAutomationStatus(queued.batchId),
|
|
3206
|
+
sleep: ms => delay(ms),
|
|
3207
|
+
intervalMs: parsePositiveIntegerFlag(ctx.flags, 'interval-ms', 5000),
|
|
3208
|
+
timeoutMs: parsePositiveIntegerFlag(ctx.flags, 'timeout-ms', 1800000),
|
|
3209
|
+
onProgress: lines => lines.forEach(line => stderr.write(`${line}\n`)),
|
|
3210
|
+
});
|
|
3211
|
+
}
|
|
3212
|
+
let composeExecution;
|
|
3213
|
+
if (needsFallbackCompose) {
|
|
3214
|
+
const order = queued.images[0];
|
|
3215
|
+
if (!order)
|
|
3216
|
+
throw new Error('Automation did not return an order for the requested image.');
|
|
3217
|
+
if (batchStatus?.images.find(image => image.orderId === order.orderId)
|
|
3218
|
+
?.status === 'failed')
|
|
3219
|
+
throw new Error(`Automation failed for order ${order.orderId}; there is nothing to compose.`);
|
|
3220
|
+
const runs = await ctx.client.v2.listCanvasRuns(session.canvas.id, { limit: 200 });
|
|
3221
|
+
const parts = buildComposerPartsFromMeshExecutions(runs.items, order.orderId);
|
|
3222
|
+
const fullBodyImageAssetId = resolveFullBodyImageAssetId(runs.items, order.orderId) ??
|
|
3223
|
+
(detected.kind === 'resourceId' ? detected.resourceId : undefined);
|
|
3224
|
+
if (parts.length === 0 || fullBodyImageAssetId == null) {
|
|
3225
|
+
throw withErrorHint(new Error('Could not find mesh part outputs (and the source image they were generated from) to compose for this order.'));
|
|
3226
|
+
}
|
|
3227
|
+
try {
|
|
3228
|
+
const composeQueued = await executeRecorded(session, 'mesh.compose', {
|
|
3229
|
+
parts,
|
|
3230
|
+
fullBodyImageAssetId,
|
|
3231
|
+
agentVersion: 'v6',
|
|
3232
|
+
}, executionOptions(ctx.flags));
|
|
3233
|
+
composeExecution = composeQueued.execution;
|
|
3234
|
+
}
|
|
3235
|
+
catch (error) {
|
|
3236
|
+
throw error instanceof Error ? withErrorHint(error) : error;
|
|
3237
|
+
}
|
|
3238
|
+
}
|
|
3239
|
+
// The automation receipt (`queued.execution`) is only the split stage's own
|
|
3240
|
+
// execution row; the real completion signal for the whole order (mesh gen
|
|
3241
|
+
// across every part, plus compose when the server ran it) is the batch
|
|
3242
|
+
// status polled above. Once that says the order is done, re-fetch the
|
|
3243
|
+
// execution so `--download`/the printed summary reflect the final state
|
|
3244
|
+
// rather than the split-stage snapshot from right after submission.
|
|
3245
|
+
const finalExecution = composeExecution ??
|
|
3246
|
+
(batchStatus != null
|
|
3247
|
+
? await ctx.client.v2.getRun(queued.execution.runId)
|
|
3248
|
+
: queued.execution);
|
|
3249
|
+
// Prefer the server's own reported cost (#8179) over our preflight
|
|
3250
|
+
// best-effort `estimate` once we actually have it; absent on a server
|
|
3251
|
+
// that has not deployed #8179 yet, in which case only `estimate` (used
|
|
3252
|
+
// for the --max-cost gate above) is available.
|
|
3253
|
+
const serverCost = readServerCostBreakdown(queued);
|
|
3254
|
+
// The machine-readable summary this prints is always JSON, matching every
|
|
3255
|
+
// other command in this CLI; --json is accepted (it is a no-op) rather than
|
|
3256
|
+
// rejected, since there is no plain-text mode here to opt out of.
|
|
3257
|
+
print(await withOptionalDownloads(ctx.flags, sanitizeProductionOutput({
|
|
3258
|
+
batchId: queued.batchId,
|
|
3259
|
+
estimatedCostCredits: queued.estimatedCostCredits,
|
|
3260
|
+
...(serverCost ?? {}),
|
|
3261
|
+
images: queued.images,
|
|
3262
|
+
estimate,
|
|
3263
|
+
batchStatus,
|
|
3264
|
+
compose: composeExecution,
|
|
3265
|
+
execution: finalExecution,
|
|
3266
|
+
})));
|
|
3267
|
+
process.exitCode = executionExitCode(finalExecution);
|
|
3268
|
+
};
|
|
3082
3269
|
const commandProduction = async (subcommand, positionals, ctx) => {
|
|
3083
3270
|
if (subcommand === 'agents') {
|
|
3084
3271
|
print(sanitizeProductionOutput(await ctx.client.v1.getProductionAgents()));
|
|
@@ -3185,6 +3372,14 @@ const commandProduction = async (subcommand, positionals, ctx) => {
|
|
|
3185
3372
|
return;
|
|
3186
3373
|
}
|
|
3187
3374
|
if (subcommand === 'run') {
|
|
3375
|
+
// `production run --image <file|assetId>` is a different command in
|
|
3376
|
+
// everything but name: the one-shot image -> finished-asset flow, not
|
|
3377
|
+
// confirmed-task mission execution. Intercept before `--order-id` is
|
|
3378
|
+
// required so the mission flow below is completely untouched when
|
|
3379
|
+
// --image is absent.
|
|
3380
|
+
if (getFlag(ctx.flags, 'image') != null) {
|
|
3381
|
+
return commandProductionRunOneShot(ctx);
|
|
3382
|
+
}
|
|
3188
3383
|
const orderId = requireFlag(ctx.flags, 'order-id');
|
|
3189
3384
|
const missionId = requireFlag(ctx.flags, 'mission-id');
|
|
3190
3385
|
const runMode = parseRunModeFlag(ctx.flags);
|
|
@@ -3879,12 +4074,21 @@ const commandRuns = async (subcommand, positionals, ctx) => {
|
|
|
3879
4074
|
print(await ctx.client.v2.listCanvasRuns(canvas.id, pageOptions(ctx.flags)));
|
|
3880
4075
|
return;
|
|
3881
4076
|
}
|
|
3882
|
-
if (subcommand === 'get' || subcommand === 'watch') {
|
|
4077
|
+
if (subcommand === 'get' || subcommand === 'watch' || subcommand === 'wait') {
|
|
3883
4078
|
const id = requirePositional(positionals, 2, 'run-id');
|
|
4079
|
+
// `wait` is `watch` under a name that matches how long-running waits are
|
|
4080
|
+
// asked for elsewhere in the CLI; both poll the same way (429s are
|
|
4081
|
+
// retried inside the client's own request layer, same as every other
|
|
4082
|
+
// poll loop in this file) and accept the same --interval-ms/--timeout-ms.
|
|
3884
4083
|
const execution = subcommand === 'get'
|
|
3885
4084
|
? await ctx.client.v2.getRun(id)
|
|
3886
4085
|
: await waitForExecution(ctx.client, id, watchOptions(ctx.flags));
|
|
3887
|
-
|
|
4086
|
+
if (subcommand === 'get' && hasFlag(ctx.flags, 'summary')) {
|
|
4087
|
+
stdout.write(`${formatExecutionSummaryLines(execution).join('\n')}\n`);
|
|
4088
|
+
}
|
|
4089
|
+
else {
|
|
4090
|
+
print({ execution });
|
|
4091
|
+
}
|
|
3888
4092
|
process.exitCode = executionExitCode(execution);
|
|
3889
4093
|
return;
|
|
3890
4094
|
}
|
|
@@ -4003,6 +4207,20 @@ const parseNonNegativeIntegerFlag = (flags, name) => {
|
|
|
4003
4207
|
}
|
|
4004
4208
|
return parsed;
|
|
4005
4209
|
};
|
|
4210
|
+
/** Base URL and workspace an MCP entry should target: explicit flags, then the selected profile, then defaults. */
|
|
4211
|
+
const resolveMcpTarget = async (flags) => {
|
|
4212
|
+
const config = await readAuthConfig(getConfigPath(flags));
|
|
4213
|
+
const explicitProfile = getFlag(flags, 'profile');
|
|
4214
|
+
const stored = config.profiles?.[explicitProfile ?? config.defaultProfile ?? defaultProfileName];
|
|
4215
|
+
if (explicitProfile && !stored)
|
|
4216
|
+
throw new Error('Selected profile does not exist');
|
|
4217
|
+
const selected = explicitProfile || stored?.workspaceId || isPersonalProfile(stored);
|
|
4218
|
+
const baseUrl = getFlag(flags, 'base-url') ??
|
|
4219
|
+
(selected ? stored?.baseUrl : env.ASSETHUB_API_BASE_URL ?? stored?.baseUrl) ?? defaultBaseUrl;
|
|
4220
|
+
const workspaceId = getFlag(flags, 'workspace') ??
|
|
4221
|
+
(stored && new URL(baseUrl).origin === new URL(stored.baseUrl).origin ? stored.workspaceId : undefined);
|
|
4222
|
+
return { baseUrl, workspaceId };
|
|
4223
|
+
};
|
|
4006
4224
|
const run = async () => {
|
|
4007
4225
|
const parsed = parseArgs(argv.slice(2));
|
|
4008
4226
|
if (hasFlag(parsed.flags, 'version')) {
|
|
@@ -4014,6 +4232,20 @@ const run = async () => {
|
|
|
4014
4232
|
return;
|
|
4015
4233
|
}
|
|
4016
4234
|
const [command, subcommand] = parsed.positionals;
|
|
4235
|
+
if (command !== 'init')
|
|
4236
|
+
await syncInstalledSkill();
|
|
4237
|
+
if (command === 'init') {
|
|
4238
|
+
if (subcommand)
|
|
4239
|
+
throw new Error(`Use init [--agent ${AGENT_IDS.join('|')}] [--project] [--dry-run]`);
|
|
4240
|
+
const target = await resolveMcpTarget(parsed.flags);
|
|
4241
|
+
print(await initAgents({
|
|
4242
|
+
...target,
|
|
4243
|
+
agents: getFlagValues(parsed.flags, 'agent').map(value => assertFlagHasValue(value, '--agent <name>')),
|
|
4244
|
+
project: hasFlag(parsed.flags, 'project'),
|
|
4245
|
+
dryRun: hasFlag(parsed.flags, 'dry-run'),
|
|
4246
|
+
}));
|
|
4247
|
+
return;
|
|
4248
|
+
}
|
|
4017
4249
|
if (command === 'mcp' && subcommand === 'tools') {
|
|
4018
4250
|
stderr.write('Discovering AssetHub MCP tools…\n');
|
|
4019
4251
|
const report = await diagnose({
|
|
@@ -4050,16 +4282,7 @@ const run = async () => {
|
|
|
4050
4282
|
if (command === 'mcp') {
|
|
4051
4283
|
if (subcommand !== 'config')
|
|
4052
4284
|
throw new Error('Use mcp tools [tool-name] or mcp config --client cursor|codex');
|
|
4053
|
-
const
|
|
4054
|
-
const explicitProfile = getFlag(parsed.flags, 'profile');
|
|
4055
|
-
const stored = config.profiles?.[explicitProfile ?? config.defaultProfile ?? defaultProfileName];
|
|
4056
|
-
if (explicitProfile && !stored)
|
|
4057
|
-
throw new Error('Selected profile does not exist');
|
|
4058
|
-
const selected = explicitProfile || stored?.workspaceId || isPersonalProfile(stored);
|
|
4059
|
-
const baseUrl = getFlag(parsed.flags, 'base-url') ??
|
|
4060
|
-
(selected ? stored?.baseUrl : env.ASSETHUB_API_BASE_URL ?? stored?.baseUrl) ?? defaultBaseUrl;
|
|
4061
|
-
const workspaceId = getFlag(parsed.flags, 'workspace') ??
|
|
4062
|
-
(stored && new URL(baseUrl).origin === new URL(stored.baseUrl).origin ? stored.workspaceId : undefined);
|
|
4285
|
+
const { baseUrl, workspaceId } = await resolveMcpTarget(parsed.flags);
|
|
4063
4286
|
stdout.write(mcpConfig(requireFlag(parsed.flags, 'client'), baseUrl, hasFlag(parsed.flags, 'account'), workspaceId));
|
|
4064
4287
|
return;
|
|
4065
4288
|
}
|