@assethub/cli 0.1.22 → 0.1.24
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 +25 -0
- package/dist/index.d.ts +23 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +215 -9
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -2,6 +2,31 @@
|
|
|
2
2
|
|
|
3
3
|
Command line interface for AssetHub.
|
|
4
4
|
|
|
5
|
+
## API discovery and Workspace Skills
|
|
6
|
+
|
|
7
|
+
Use `api search [query]` to discover the authenticated server catalog and
|
|
8
|
+
`api describe "METHOD /path"` to inspect an exact request contract. `api call`
|
|
9
|
+
accepts `--path-json`, `--query-json`, and `--input-json` (inline JSON or `@file`).
|
|
10
|
+
Mutations require an explicit stable `--operation-id <uuid>`. Preserve that UUID
|
|
11
|
+
and exact inputs; inspect any returned run ID before retrying uncertain work.
|
|
12
|
+
The server's workspace, gate, billing, and terminal-result rules still apply.
|
|
13
|
+
|
|
14
|
+
`skills list|get|learn|update|controls|prepare|proposal|accept` uses the existing
|
|
15
|
+
Workspace Skills API. Read `--help` for required revisions and JSON inputs.
|
|
16
|
+
For V3.7 Artist Skills or V3.7.1 Building Modules, `production analyze` and new
|
|
17
|
+
`parts split` analyses accept
|
|
18
|
+
`--skill-mode auto|manual|off` and up to three distinct `--skill-id <id>` values.
|
|
19
|
+
Manual selection requires IDs; off rejects them. The server resolves authorized
|
|
20
|
+
published skill revisions and keeps Internal gates and actor checks in force.
|
|
21
|
+
Existing `parts split --order-id` operations reject skill flags; use
|
|
22
|
+
`runs resume` to recover the saved operation with its original selection.
|
|
23
|
+
|
|
24
|
+
For complete-object graph models, add `--context <canvas-id> --context-version <n>`
|
|
25
|
+
to `production analyze` to apply that exact saved Must/Avoid guidance. Both flags
|
|
26
|
+
are required together; `--context` also selects the execution canvas and must
|
|
27
|
+
match `--canvas` when supplied. Stale revisions and unsupported engines fail
|
|
28
|
+
before generation. Guidance does not expand the model's supported part boundaries.
|
|
29
|
+
|
|
5
30
|
## Personal API keys
|
|
6
31
|
|
|
7
32
|
Log in once with a personal key, then select its workspace:
|
package/dist/index.d.ts
CHANGED
|
@@ -1,8 +1,29 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { type AnimationRetargetRequest, type Intervention, type RigRequest } from '@assethub/api-client';
|
|
2
|
+
import { type AnimationRetargetRequest, type Intervention, type RigRequest, createAssetHubClient } from '@assethub/api-client';
|
|
3
3
|
import { buildRunUploadPlan } from './runsUpload/buildRunUpload.js';
|
|
4
4
|
type Flags = Record<string, string | boolean | string[]>;
|
|
5
|
-
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 composer models\n assethub composer refine --list-modes\n assethub composer refine --from-run <run-id> --instruction <text> [--mode standard|thorough|placement|workshop|blender] [--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>] [--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>] [--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";
|
|
5
|
+
type ResolvedAuth = {
|
|
6
|
+
apiKey: string;
|
|
7
|
+
authentication?: 'personal';
|
|
8
|
+
workspaceId?: string;
|
|
9
|
+
baseUrl: string;
|
|
10
|
+
profile: string;
|
|
11
|
+
source: 'flag' | 'env' | 'profile';
|
|
12
|
+
};
|
|
13
|
+
type CommandContext = {
|
|
14
|
+
client: ReturnType<typeof createAssetHubClient>;
|
|
15
|
+
flags: Flags;
|
|
16
|
+
auth: ResolvedAuth;
|
|
17
|
+
/**
|
|
18
|
+
* The raw argument slice, kept alongside the parsed flags because `Flags` is
|
|
19
|
+
* keyed by flag name and so cannot say which of two different flags came
|
|
20
|
+
* first. `production intervene` needs that order: an intervention batch's seq
|
|
21
|
+
* order in the log is the operator's own order of decisions.
|
|
22
|
+
*/
|
|
23
|
+
args: string[];
|
|
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";
|
|
26
|
+
export declare const commandSkills: (subcommand: string | undefined, positionals: string[], ctx: CommandContext) => Promise<void>;
|
|
6
27
|
/**
|
|
7
28
|
* The `animate retarget` request, built from flags alone.
|
|
8
29
|
*
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AA4BA,OAAO,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AA4BA,OAAO,EAQL,KAAK,wBAAwB,EAO7B,KAAK,YAAY,EAEjB,KAAK,UAAU,EAef,oBAAoB,EACrB,MAAM,sBAAsB,CAAA;AAc7B,OAAO,EAAC,kBAAkB,EAAc,MAAM,gCAAgC,CAAA;AAI9E,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;AA4HD,eAAO,MAAM,KAAK,wvcA6IjB,CAAA;AAi/CD,eAAO,MAAM,aAAa,GACxB,YAAY,MAAM,GAAG,SAAS,EAC9B,aAAa,MAAM,EAAE,EACrB,KAAK,cAAc,KAClB,OAAO,CAAC,IAAI,CA6Hd,CAAA;AA41CD;;;;;;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;AA+tCD,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
|
@@ -15,7 +15,7 @@ import { basename, dirname, extname, join, resolve } from 'node:path';
|
|
|
15
15
|
import { argv, env, exit, stdin, stderr, stdout } from 'node:process';
|
|
16
16
|
import { fileURLToPath } from 'node:url';
|
|
17
17
|
import { promisify } from 'node:util';
|
|
18
|
-
import { AssetHubApiError, WorkspaceClientError, createWorkspaceClient, createAssetHubClient, } from '@assethub/api-client';
|
|
18
|
+
import { AssetHubApiError, callApiOperation, describeApiOperation, discoverApiOperations, searchApiOperations, WorkspaceClientError, createWorkspaceClient, createAssetHubClient, } from '@assethub/api-client';
|
|
19
19
|
import { resolveCanvasSelection, saveCanvasSelection } from './canvas.js';
|
|
20
20
|
import { activeExecution, childOperationId, CliExecutionError, executeRecorded, hasRecordedOperation, openExecutionSession, resumeRecorded, waitForExecution, } from './execution.js';
|
|
21
21
|
import { buildRunUploadPlan, formatBytes } from './runsUpload/buildRunUpload.js';
|
|
@@ -36,6 +36,8 @@ const artifactGraphPartExtractorApiValues = new Set([
|
|
|
36
36
|
'ah_agent_graph_v3_6_4',
|
|
37
37
|
'ah_agent_graph_v3_6_5',
|
|
38
38
|
'ah_agent_graph_pluffy_v3_1',
|
|
39
|
+
'ah_agent_graph_v3_7',
|
|
40
|
+
'ah_agent_graph_v3_7_1',
|
|
39
41
|
]);
|
|
40
42
|
const partExtractorOptions = [
|
|
41
43
|
{
|
|
@@ -78,6 +80,16 @@ const partExtractorOptions = [
|
|
|
78
80
|
apiValue: 'ah_agent_graph_pluffy_v3_1',
|
|
79
81
|
aliases: ['pluffy', 'pluffy v3.1', 'pluffy 3.1'],
|
|
80
82
|
},
|
|
83
|
+
{
|
|
84
|
+
publicName: 'V3.7 Artist Skills',
|
|
85
|
+
apiValue: 'ah_agent_graph_v3_7',
|
|
86
|
+
aliases: ['v3.7', '3.7'],
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
publicName: 'V3.7.1 Building Modules',
|
|
90
|
+
apiValue: 'ah_agent_graph_v3_7_1',
|
|
91
|
+
aliases: ['v3.7.1', '3.7.1'],
|
|
92
|
+
},
|
|
81
93
|
];
|
|
82
94
|
const partExtractorPublicNames = partExtractorOptions
|
|
83
95
|
.map(option => option.publicName)
|
|
@@ -135,9 +147,20 @@ Usage:
|
|
|
135
147
|
assethub files upload <file> --media-type image|mesh
|
|
136
148
|
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>]
|
|
137
149
|
assethub capabilities
|
|
150
|
+
assethub api search [query]
|
|
151
|
+
assethub api describe "<METHOD /path>"
|
|
152
|
+
assethub api call "<METHOD /path>" [--path-json <json|@file>] [--query-json <json|@file>] [--input-json <json|@file|@->] [--operation-id <uuid>]
|
|
153
|
+
assethub skills list [--cursor <cursor>]
|
|
154
|
+
assethub skills get <skill-id> [--revision <n>]
|
|
155
|
+
assethub skills learn --input-json <json|@file|@-> --operation-id <uuid>
|
|
156
|
+
assethub skills update <skill-id> --input-json <json|@file|@->
|
|
157
|
+
assethub skills controls <skill-id> --revision <n> --grant-revision <n> --mode automatic|manual|off [--share]
|
|
158
|
+
assethub skills prepare --input-json <json|@file|@->
|
|
159
|
+
assethub skills proposal <proposal-id>
|
|
160
|
+
assethub skills accept <proposal-id> --input-json <json|@file|@->
|
|
138
161
|
assethub composer models
|
|
139
162
|
assethub composer refine --list-modes
|
|
140
|
-
assethub composer refine --from-run <run-id> --instruction <text> [--mode standard|thorough|placement|workshop|blender] [--max-rounds <n>] [--transforms-json <json|@file>] [--wait] [--download --out-dir <dir>]
|
|
163
|
+
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>]
|
|
141
164
|
assethub composer refine --input-json <json|@file> [--canvas <id>] [--operation-id <uuid>] [--wait] [--download --out-dir <dir>]
|
|
142
165
|
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]
|
|
143
166
|
assethub composer run --input-json <json|@file> [--canvas <id>] [--operation-id <uuid>] [--wait] [--download --out-dir <dir>]
|
|
@@ -172,7 +195,7 @@ Usage:
|
|
|
172
195
|
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>]
|
|
173
196
|
assethub jobs get <job-id> [--download --out-dir <dir>]
|
|
174
197
|
assethub jobs watch <job-id> [--interval-ms <ms>] [--timeout-ms <ms>] [--download --out-dir <dir>]
|
|
175
|
-
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>] [--wait] [--download --out-dir <dir>]
|
|
198
|
+
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>]
|
|
176
199
|
assethub production agents
|
|
177
200
|
assethub production automation --input-json <json|@file|@-> [--canvas <id>] [--operation-id <uuid>] [--wait]
|
|
178
201
|
assethub production status <order-id> [--wait] [--download --out-dir <dir>]
|
|
@@ -182,7 +205,7 @@ Usage:
|
|
|
182
205
|
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>]
|
|
183
206
|
assethub production interventions <order-id>
|
|
184
207
|
assethub runs upload <path> [--graph-id <id>] [--stream-id <id>] [--rev <n>] [--description <text>] [--tag <tag>...] [--skip-register] [--dry-run]
|
|
185
|
-
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>] [--wait] [--task-id <id>...] [--mission-id <id>] [--all-ready] [--download --out-dir <dir>]
|
|
208
|
+
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>]
|
|
186
209
|
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>]
|
|
187
210
|
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>]
|
|
188
211
|
|
|
@@ -313,6 +336,30 @@ const resolvePartExtractorApiValue = (value) => {
|
|
|
313
336
|
return option.apiValue;
|
|
314
337
|
};
|
|
315
338
|
const resolvePartExtractorForAnalyze = (flags) => resolvePartExtractorApiValue(getPartExtractorFlag(flags) ?? defaultPartExtractorName);
|
|
339
|
+
const resolveProductionSkillSelection = (flags, agentVersion) => {
|
|
340
|
+
const mode = getFlag(flags, 'skill-mode');
|
|
341
|
+
const skillIds = getFlagValues(flags, 'skill-id').map(value => assertFlagHasValue(value, '--skill-id <id>'));
|
|
342
|
+
if (mode == null) {
|
|
343
|
+
if (skillIds.length > 0)
|
|
344
|
+
throw new Error('--skill-id requires --skill-mode');
|
|
345
|
+
return undefined;
|
|
346
|
+
}
|
|
347
|
+
if (mode !== 'auto' && mode !== 'manual' && mode !== 'off')
|
|
348
|
+
throw new Error('--skill-mode must be "auto", "manual", or "off"');
|
|
349
|
+
if (!['ah_agent_graph_v3_7', 'ah_agent_graph_v3_7_1'].includes(agentVersion))
|
|
350
|
+
throw new Error('--skill-mode requires V3.7 Artist Skills or V3.7.1 Building Modules');
|
|
351
|
+
if (skillIds.length > 3)
|
|
352
|
+
throw new Error('--skill-id accepts at most 3 values');
|
|
353
|
+
if (new Set(skillIds).size !== skillIds.length)
|
|
354
|
+
throw new Error('--skill-id values must be unique');
|
|
355
|
+
if (skillIds.some(skillId => !/^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$/.test(skillId)))
|
|
356
|
+
throw new Error('--skill-id contains an invalid workspace skill ID');
|
|
357
|
+
if (mode === 'manual' && skillIds.length === 0)
|
|
358
|
+
throw new Error('--skill-mode manual requires at least one --skill-id');
|
|
359
|
+
if (mode === 'off' && skillIds.length > 0)
|
|
360
|
+
throw new Error('--skill-mode off does not accept --skill-id');
|
|
361
|
+
return { mode, skillIds };
|
|
362
|
+
};
|
|
316
363
|
const publicPartExtractorName = (value) => {
|
|
317
364
|
if (value == null) {
|
|
318
365
|
return null;
|
|
@@ -1275,6 +1322,112 @@ const commandSource = async (subcommand, ctx) => {
|
|
|
1275
1322
|
}
|
|
1276
1323
|
print({ source, fileRef: source.fileRef, mediaType });
|
|
1277
1324
|
};
|
|
1325
|
+
const commandApi = async (subcommand, positionals, ctx) => {
|
|
1326
|
+
if (!['search', 'describe', 'call'].includes(subcommand ?? ''))
|
|
1327
|
+
throw new Error('Use api search|describe|call. Mutations require --operation-id.');
|
|
1328
|
+
const discovery = await discoverApiOperations(ctx.client);
|
|
1329
|
+
if (subcommand === 'search') {
|
|
1330
|
+
print({
|
|
1331
|
+
operations: searchApiOperations(discovery.catalog, positionals.slice(2).join(' ')),
|
|
1332
|
+
});
|
|
1333
|
+
return;
|
|
1334
|
+
}
|
|
1335
|
+
const operation = requirePositional(positionals, 2, 'operation');
|
|
1336
|
+
if (subcommand === 'describe') {
|
|
1337
|
+
const found = discovery.catalog.get(operation);
|
|
1338
|
+
if (!found)
|
|
1339
|
+
throw new Error('Unknown operation. Use api search first.');
|
|
1340
|
+
print(describeApiOperation(found, discovery.specs[found.path.startsWith('/api/v1/') ? 'v1' : 'v2']));
|
|
1341
|
+
return;
|
|
1342
|
+
}
|
|
1343
|
+
const pathJson = getFlag(ctx.flags, 'path-json');
|
|
1344
|
+
const queryJson = getFlag(ctx.flags, 'query-json');
|
|
1345
|
+
const bodyJson = getFlag(ctx.flags, 'input-json');
|
|
1346
|
+
const operationId = getFlag(ctx.flags, 'operation-id');
|
|
1347
|
+
activeExecution.operationId = operationId;
|
|
1348
|
+
try {
|
|
1349
|
+
print(await callApiOperation(ctx.client, discovery, {
|
|
1350
|
+
operation,
|
|
1351
|
+
operationId,
|
|
1352
|
+
path: pathJson
|
|
1353
|
+
? (await readJsonArgument(pathJson, '--path-json'))
|
|
1354
|
+
: undefined,
|
|
1355
|
+
query: queryJson
|
|
1356
|
+
? (await readJsonArgument(queryJson, '--query-json'))
|
|
1357
|
+
: undefined,
|
|
1358
|
+
body: bodyJson
|
|
1359
|
+
? await readJsonArgument(bodyJson, '--input-json')
|
|
1360
|
+
: undefined,
|
|
1361
|
+
}));
|
|
1362
|
+
}
|
|
1363
|
+
catch (error) {
|
|
1364
|
+
if (error instanceof AssetHubApiError && error.runId)
|
|
1365
|
+
activeExecution.runId = error.runId;
|
|
1366
|
+
throw error;
|
|
1367
|
+
}
|
|
1368
|
+
};
|
|
1369
|
+
export const commandSkills = async (subcommand, positionals, ctx) => {
|
|
1370
|
+
if (subcommand === 'list') {
|
|
1371
|
+
print(await ctx.client.v2.listWorkspaceSkills({
|
|
1372
|
+
cursor: getFlag(ctx.flags, 'cursor'),
|
|
1373
|
+
}));
|
|
1374
|
+
return;
|
|
1375
|
+
}
|
|
1376
|
+
if (subcommand === 'get') {
|
|
1377
|
+
print(await ctx.client.v2.getWorkspaceSkill(requirePositional(positionals, 2, 'skill-id'), {
|
|
1378
|
+
revision: hasFlag(ctx.flags, 'revision')
|
|
1379
|
+
? parsePositiveIntegerFlag(ctx.flags, 'revision', 1)
|
|
1380
|
+
: undefined,
|
|
1381
|
+
}));
|
|
1382
|
+
return;
|
|
1383
|
+
}
|
|
1384
|
+
if (subcommand === 'controls') {
|
|
1385
|
+
const mode = parseEnumFlag(ctx.flags, 'mode', [
|
|
1386
|
+
'automatic',
|
|
1387
|
+
'manual',
|
|
1388
|
+
'off',
|
|
1389
|
+
]);
|
|
1390
|
+
if (!mode)
|
|
1391
|
+
throw new Error('Missing required flag: --mode');
|
|
1392
|
+
requireFlag(ctx.flags, 'revision');
|
|
1393
|
+
requireFlag(ctx.flags, 'grant-revision');
|
|
1394
|
+
print(await ctx.client.v2.setWorkspaceSkillControls(requirePositional(positionals, 2, 'skill-id'), {
|
|
1395
|
+
expectedRevision: parsePositiveIntegerFlag(ctx.flags, 'revision', 1),
|
|
1396
|
+
expectedGrantRevision: parsePositiveIntegerFlag(ctx.flags, 'grant-revision', 1),
|
|
1397
|
+
mode,
|
|
1398
|
+
...(hasFlag(ctx.flags, 'share') ? { share: true } : {}),
|
|
1399
|
+
}));
|
|
1400
|
+
return;
|
|
1401
|
+
}
|
|
1402
|
+
if (subcommand === 'proposal') {
|
|
1403
|
+
print(await ctx.client.v2.getWorkspaceSkillProposal(requirePositional(positionals, 2, 'proposal-id')));
|
|
1404
|
+
return;
|
|
1405
|
+
}
|
|
1406
|
+
if (['learn', 'prepare'].includes(subcommand ?? '')) {
|
|
1407
|
+
const input = await readJsonArgument(requireFlag(ctx.flags, 'input-json'), '--input-json');
|
|
1408
|
+
const operationId = subcommand === 'learn'
|
|
1409
|
+
? requireFlag(ctx.flags, 'operation-id')
|
|
1410
|
+
: undefined;
|
|
1411
|
+
if (operationId != null &&
|
|
1412
|
+
!/^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(operationId))
|
|
1413
|
+
throw new Error('--operation-id must be a UUID; reuse the same ID and input after an uncertain response');
|
|
1414
|
+
if (operationId != null)
|
|
1415
|
+
activeExecution.operationId = operationId;
|
|
1416
|
+
print(subcommand === 'learn'
|
|
1417
|
+
? await ctx.client.v2.learnWorkspaceSkill(input, { idempotencyKey: operationId })
|
|
1418
|
+
: await ctx.client.v2.prepareWorkspaceSkillProposal(input));
|
|
1419
|
+
return;
|
|
1420
|
+
}
|
|
1421
|
+
if (['update', 'accept'].includes(subcommand ?? '')) {
|
|
1422
|
+
const id = requirePositional(positionals, 2, subcommand === 'update' ? 'skill-id' : 'proposal-id');
|
|
1423
|
+
const input = await readJsonArgument(requireFlag(ctx.flags, 'input-json'), '--input-json');
|
|
1424
|
+
print(subcommand === 'update'
|
|
1425
|
+
? await ctx.client.v2.updateWorkspaceSkill(id, input)
|
|
1426
|
+
: await ctx.client.v2.acceptWorkspaceSkillProposal(id, input));
|
|
1427
|
+
return;
|
|
1428
|
+
}
|
|
1429
|
+
throw new Error('Use skills list|get|learn|update|controls|prepare|proposal|accept');
|
|
1430
|
+
};
|
|
1278
1431
|
const commandModels = async (subcommand, positionals, ctx) => {
|
|
1279
1432
|
if (subcommand === 'list') {
|
|
1280
1433
|
const domain = getFlag(ctx.flags, 'domain');
|
|
@@ -1966,6 +2119,7 @@ const meshRefinementModes = [
|
|
|
1966
2119
|
'placement',
|
|
1967
2120
|
'workshop',
|
|
1968
2121
|
'blender',
|
|
2122
|
+
'codex',
|
|
1969
2123
|
];
|
|
1970
2124
|
const refinementTransforms = (value, flag) => {
|
|
1971
2125
|
if (value == null || typeof value !== 'object' || Array.isArray(value))
|
|
@@ -1997,6 +2151,10 @@ const refinementModeInfo = (capabilities, mode) => {
|
|
|
1997
2151
|
throw new Error(`Refinement mode ${mode} is unavailable${info.reason ? `: ${info.reason}` : ''}`);
|
|
1998
2152
|
return info;
|
|
1999
2153
|
};
|
|
2154
|
+
const refinementContinuationFields = [
|
|
2155
|
+
'geometryBackend', 'referenceMode', 'calibration', 'referenceViews',
|
|
2156
|
+
'geometrySources', 'reviewContext', 'background',
|
|
2157
|
+
];
|
|
2000
2158
|
/** Reuse the frozen sources and latest editable scene, never replay server-only receipt fields. */
|
|
2001
2159
|
const composerInputFromRun = (previous, operation) => {
|
|
2002
2160
|
const source = previous.resolvedInput ?? previous.input ?? previous.requestedInput ?? {};
|
|
@@ -2012,7 +2170,14 @@ const composerInputFromRun = (previous, operation) => {
|
|
|
2012
2170
|
'quickRunId',
|
|
2013
2171
|
'quickScene',
|
|
2014
2172
|
]
|
|
2015
|
-
: [
|
|
2173
|
+
: [
|
|
2174
|
+
'fullBodyImageAssetId',
|
|
2175
|
+
'agentRuntime',
|
|
2176
|
+
'mode',
|
|
2177
|
+
'instruction',
|
|
2178
|
+
'maxRounds',
|
|
2179
|
+
...refinementContinuationFields,
|
|
2180
|
+
];
|
|
2016
2181
|
const input = Object.fromEntries(fields
|
|
2017
2182
|
.filter(key => source[key] !== undefined)
|
|
2018
2183
|
.map(key => [key, source[key]]));
|
|
@@ -2036,6 +2201,13 @@ const composerInputFromRun = (previous, operation) => {
|
|
|
2036
2201
|
if (transforms != null)
|
|
2037
2202
|
input.transforms = transforms;
|
|
2038
2203
|
if (operation === 'mesh.refine') {
|
|
2204
|
+
for (const key of ['calibration', 'referenceViews', 'geometrySources']) {
|
|
2205
|
+
if (previous.refinement?.[key] != null)
|
|
2206
|
+
input[key] = previous.refinement[key];
|
|
2207
|
+
}
|
|
2208
|
+
const reviewContext = previous.refinement?.report?.reviewContext;
|
|
2209
|
+
if (reviewContext != null)
|
|
2210
|
+
input.reviewContext = reviewContext;
|
|
2039
2211
|
const referenceTransform = previous.composition?.referenceTransform ?? source.referenceTransform;
|
|
2040
2212
|
if (referenceTransform != null)
|
|
2041
2213
|
input.referenceTransform = referenceTransform;
|
|
@@ -2097,6 +2269,8 @@ const commandComposerRefine = async (ctx) => {
|
|
|
2097
2269
|
capabilities.defaultMode;
|
|
2098
2270
|
if (!meshRefinementModes.includes(mode))
|
|
2099
2271
|
throw new Error(`--mode must be one of: ${meshRefinementModes.join(', ')}`);
|
|
2272
|
+
if (mode !== 'codex' && (input.geometryBackend || input.referenceMode === 'all_angles' || input.background))
|
|
2273
|
+
throw new Error('Saved Blender-backend, all-angle or background settings require codex mode; use --input-json with settings matching the new mode');
|
|
2100
2274
|
const modeInfo = refinementModeInfo(capabilities, mode);
|
|
2101
2275
|
const maxRoundsFlag = getFlag(ctx.flags, 'max-rounds');
|
|
2102
2276
|
const inputMaxRounds = input.maxRounds;
|
|
@@ -2129,6 +2303,9 @@ const commandComposerRefine = async (ctx) => {
|
|
|
2129
2303
|
operation: 'mesh.refine',
|
|
2130
2304
|
});
|
|
2131
2305
|
const body = {
|
|
2306
|
+
...Object.fromEntries(refinementContinuationFields
|
|
2307
|
+
.filter(key => input[key] !== undefined)
|
|
2308
|
+
.map(key => [key, input[key]])),
|
|
2132
2309
|
parts: refinementParts,
|
|
2133
2310
|
fullBodyImageAssetId: input.fullBodyImageAssetId,
|
|
2134
2311
|
transforms,
|
|
@@ -2893,9 +3070,9 @@ const readOpsJsonFlag = async (flags) => {
|
|
|
2893
3070
|
}
|
|
2894
3071
|
return parsed;
|
|
2895
3072
|
};
|
|
2896
|
-
const productionSession = (ctx, operation) => openExecutionSession({
|
|
3073
|
+
const productionSession = (ctx, operation, canvasId = selectedCanvasId(ctx.flags)) => openExecutionSession({
|
|
2897
3074
|
...stateOptions(ctx),
|
|
2898
|
-
canvasId
|
|
3075
|
+
canvasId,
|
|
2899
3076
|
operation,
|
|
2900
3077
|
});
|
|
2901
3078
|
const commandProduction = async (subcommand, positionals, ctx) => {
|
|
@@ -2904,11 +3081,28 @@ const commandProduction = async (subcommand, positionals, ctx) => {
|
|
|
2904
3081
|
return;
|
|
2905
3082
|
}
|
|
2906
3083
|
if (subcommand === 'analyze') {
|
|
2907
|
-
const
|
|
3084
|
+
const agentVersion = resolvePartExtractorForAnalyze(ctx.flags);
|
|
3085
|
+
const skillSelection = resolveProductionSkillSelection(ctx.flags, agentVersion);
|
|
3086
|
+
const projectContext = hasFlag(ctx.flags, 'context') || hasFlag(ctx.flags, 'context-version')
|
|
3087
|
+
? {
|
|
3088
|
+
canvasId: Number(requireFlag(ctx.flags, 'context')),
|
|
3089
|
+
version: Number(requireFlag(ctx.flags, 'context-version')),
|
|
3090
|
+
}
|
|
3091
|
+
: undefined;
|
|
3092
|
+
if (projectContext) {
|
|
3093
|
+
if (Object.values(projectContext).some(value => !Number.isSafeInteger(value) || value <= 0))
|
|
3094
|
+
throw new Error('--context and --context-version must be positive integers');
|
|
3095
|
+
const canvasId = selectedCanvasId(ctx.flags);
|
|
3096
|
+
if (canvasId != null && canvasId !== projectContext.canvasId)
|
|
3097
|
+
throw new Error('--context must match --canvas');
|
|
3098
|
+
}
|
|
3099
|
+
const session = await productionSession(ctx, 'production.analyze', projectContext?.canvasId);
|
|
2908
3100
|
const analyzed = await executeRecorded(session, 'production.analyze', {
|
|
2909
3101
|
...(await resolveProductionAnalyzeSource(ctx)),
|
|
2910
|
-
agentVersion
|
|
3102
|
+
agentVersion,
|
|
2911
3103
|
name: getFlag(ctx.flags, 'name'),
|
|
3104
|
+
...(skillSelection == null ? {} : { skillSelection }),
|
|
3105
|
+
...(projectContext == null ? {} : { projectContext }),
|
|
2912
3106
|
}, executionOptions(ctx.flags));
|
|
2913
3107
|
await printRecorded(ctx, analyzed);
|
|
2914
3108
|
return;
|
|
@@ -3091,11 +3285,16 @@ const commandParts = async (subcommand, ctx) => {
|
|
|
3091
3285
|
let orderId = source == null ? getFlag(ctx.flags, 'order-id') : undefined;
|
|
3092
3286
|
if (orderId != null) {
|
|
3093
3287
|
orderId = assertFlagHasValue(orderId, '--order-id <id>');
|
|
3288
|
+
if (hasFlag(ctx.flags, 'skill-mode') || hasFlag(ctx.flags, 'skill-id'))
|
|
3289
|
+
throw new Error('--skill-mode and --skill-id cannot be changed with --order-id; use runs resume to preserve the saved selection');
|
|
3094
3290
|
}
|
|
3095
3291
|
const partExtractorFlag = getPartExtractorFlag(ctx.flags);
|
|
3096
3292
|
const requestedAgentVersion = orderId == null || partExtractorFlag != null
|
|
3097
3293
|
? resolvePartExtractorApiValue(partExtractorFlag ?? defaultPartExtractorName)
|
|
3098
3294
|
: undefined;
|
|
3295
|
+
const skillSelection = requestedAgentVersion == null
|
|
3296
|
+
? undefined
|
|
3297
|
+
: resolveProductionSkillSelection(ctx.flags, requestedAgentVersion);
|
|
3099
3298
|
if (requestedAgentVersion != null &&
|
|
3100
3299
|
artifactGraphPartExtractorApiValues.has(requestedAgentVersion)) {
|
|
3101
3300
|
const publicName = publicPartExtractorName(requestedAgentVersion);
|
|
@@ -3115,6 +3314,7 @@ const commandParts = async (subcommand, ctx) => {
|
|
|
3115
3314
|
...(source ?? (await resolveProductionAnalyzeSource(ctx))),
|
|
3116
3315
|
agentVersion: resolvePartExtractorForAnalyze(ctx.flags),
|
|
3117
3316
|
name: getFlag(ctx.flags, 'name'),
|
|
3317
|
+
...(skillSelection == null ? {} : { skillSelection }),
|
|
3118
3318
|
}, { ...executionOptions(ctx.flags), operationId });
|
|
3119
3319
|
analyzed = result;
|
|
3120
3320
|
execution = result.execution;
|
|
@@ -3930,6 +4130,12 @@ const run = async () => {
|
|
|
3930
4130
|
}
|
|
3931
4131
|
const ctx = await createContext(parsed.flags, argv.slice(2));
|
|
3932
4132
|
switch (command) {
|
|
4133
|
+
case 'api':
|
|
4134
|
+
await commandApi(subcommand, parsed.positionals, ctx);
|
|
4135
|
+
return;
|
|
4136
|
+
case 'skills':
|
|
4137
|
+
await commandSkills(subcommand, parsed.positionals, ctx);
|
|
4138
|
+
return;
|
|
3933
4139
|
case 'composer':
|
|
3934
4140
|
await commandComposer(subcommand, ctx);
|
|
3935
4141
|
return;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@assethub/cli",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.24",
|
|
4
4
|
"description": "Command line interface for AssetHub.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
"access": "public"
|
|
31
31
|
},
|
|
32
32
|
"dependencies": {
|
|
33
|
-
"@assethub/api-client": "^0.1.
|
|
33
|
+
"@assethub/api-client": "^0.1.11",
|
|
34
34
|
"@modelcontextprotocol/sdk": "^1.30.0"
|
|
35
35
|
},
|
|
36
36
|
"repository": {
|