@assethub/cli 0.1.12 → 0.1.14
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 +46 -7
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +40 -7
- package/dist/setup.d.ts +4 -2
- package/dist/setup.d.ts.map +1 -1
- package/dist/setup.js +21 -15
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -15,8 +15,8 @@ assethub mcp config --client codex
|
|
|
15
15
|
MCP initialization and tool discovery, without invoking any tool or generating
|
|
16
16
|
assets. It returns JSON and exit 0 when checks pass, or exit 2 with a diagnostic
|
|
17
17
|
and next step when a check fails. The default total timeout is 15 seconds; change
|
|
18
|
-
it with `--timeout-ms`. Hosted MCP
|
|
19
|
-
|
|
18
|
+
it with `--timeout-ms`. Hosted MCP accepts a workspace API key from any AssetHub
|
|
19
|
+
user; account operations use a separate user access token.
|
|
20
20
|
|
|
21
21
|
`mcp config` outputs a Cursor JSON object or Codex TOML section to merge into
|
|
22
22
|
existing user settings. It does not write files or read your saved API key.
|
|
@@ -35,8 +35,7 @@ Diagnostics omit API keys and raw server error bodies.
|
|
|
35
35
|
|
|
36
36
|
## Historical meshes and artifact graphs
|
|
37
37
|
|
|
38
|
-
|
|
39
|
-
to the selected workspace, including assets created in the UI. Mesh search
|
|
38
|
+
Lists are scoped to the selected workspace, including assets created in the UI. Mesh search
|
|
40
39
|
includes parts, revisions, and archived meshes, and excludes samples.
|
|
41
40
|
|
|
42
41
|
```sh
|
|
@@ -58,7 +57,7 @@ with `--graph`. Mesh IDs returned by search can be passed to `composer run`.
|
|
|
58
57
|
|
|
59
58
|
## Agent generation with canvas history
|
|
60
59
|
|
|
61
|
-
|
|
60
|
+
Canvas execution is available to all authenticated users. Run `assethub capabilities`
|
|
62
61
|
first. Image, mesh, parts split, and production analyze/execute/automation refuse to dispatch if canvas history is unavailable.
|
|
63
62
|
The current public API remains compatible with clients that omit `executionContext`.
|
|
64
63
|
|
|
@@ -474,5 +473,45 @@ assethub mcp tools image_generate --profile my-workspace
|
|
|
474
473
|
The first command returns a compact list of tools and their action annotations.
|
|
475
474
|
The second returns the live description and input schema for one tool, including
|
|
476
475
|
required fields. Both use the selected profile and the same bounded checks as
|
|
477
|
-
`doctor --mcp`; they do not invoke tools or spend credits.
|
|
478
|
-
|
|
476
|
+
`doctor --mcp`; they do not invoke tools or spend credits. Discover names first
|
|
477
|
+
because server capabilities can change.
|
|
478
|
+
|
|
479
|
+
|
|
480
|
+
### Team members
|
|
481
|
+
|
|
482
|
+
Use a **user access token** with `auth login --access-token-stdin`. A workspace
|
|
483
|
+
API key cannot invite people or change membership. Commands use the selected
|
|
484
|
+
workspace; `--workspace <id>` explicitly selects a target without changing your
|
|
485
|
+
saved selection. Membership reads require team membership; changes require admin
|
|
486
|
+
permission. The target workspace's MFA and IP restrictions apply.
|
|
487
|
+
|
|
488
|
+
```sh
|
|
489
|
+
assethub workspace members --workspace <workspace-id>
|
|
490
|
+
assethub workspace invite --workspace <workspace-id> --email colleague@example.com
|
|
491
|
+
assethub workspace set-role <user-id> --role admin --workspace <workspace-id>
|
|
492
|
+
assethub workspace remove-member <user-id> --workspace <workspace-id>
|
|
493
|
+
```
|
|
494
|
+
|
|
495
|
+
Invite defaults to `user`; use `--role admin` deliberately. Invitations grant
|
|
496
|
+
membership and send email. An existing member returns `already_member`, preserving
|
|
497
|
+
their role and avoiding another email. Use `workspace invite --email ... --resend`
|
|
498
|
+
only to explicitly resend or recover failed delivery. If a request is interrupted,
|
|
499
|
+
check `workspace members` first. Removal revokes workspace membership, not the
|
|
500
|
+
user's account. The final admin cannot be demoted or removed.
|
|
501
|
+
|
|
502
|
+
For MCP account operations, add a separate server using:
|
|
503
|
+
|
|
504
|
+
```sh
|
|
505
|
+
assethub mcp config --client codex --account
|
|
506
|
+
assethub mcp config --client cursor --account
|
|
507
|
+
assethub mcp tools --account --profile <user-profile>
|
|
508
|
+
```
|
|
509
|
+
|
|
510
|
+
The generated configuration references `ASSETHUB_ACCESS_TOKEN` and
|
|
511
|
+
`ASSETHUB_WORKSPACE_MFA_COOKIE` without printing credentials. Set the latter to
|
|
512
|
+
`ah_workspace_mfa=<signed-cookie-value>` from the same verified browser session
|
|
513
|
+
(or an empty string if workspace MFA is not required). Pass these environment
|
|
514
|
+
variables to your MCP client and reconnect. This server uses
|
|
515
|
+
`https://app.assethub.io/api/workspaces/mcp` and exposes `workspace_list`,
|
|
516
|
+
`workspace_members_list`, `workspace_member_invite`, `workspace_member_set_role`,
|
|
517
|
+
and `workspace_member_remove`. Keep the existing API-key MCP server for generation.
|
package/dist/index.d.ts
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { type AnimationRetargetRequest, type Intervention, type RigRequest } 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\nInternal preview: canvas/context/layout and moodboards require workspace feature access.\n\nUsage:\n assethub --version\n assethub doctor [--mcp] [--profile <name>] [--timeout-ms <n>]\n assethub mcp tools [tool-name] [--profile <name>] [--timeout-ms <n>]\n assethub mcp config --client cursor|codex [--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|get\n assethub workspace create --name <name> [--operation-id <uuid>]\n assethub workspace use <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 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 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 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 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 --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
|
+
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|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 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 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 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 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 --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";
|
|
6
6
|
/**
|
|
7
7
|
* The `animate retarget` request, built from flags alone.
|
|
8
8
|
*
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAsBA,OAAO,EAIL,KAAK,wBAAwB,EAO7B,KAAK,YAAY,EAEjB,KAAK,UAAU,EAYhB,MAAM,sBAAsB,CAAA;AAa7B,OAAO,EAAC,kBAAkB,EAAc,MAAM,gCAAgC,CAAA;AAI9E,KAAK,KAAK,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,GAAG,MAAM,EAAE,CAAC,CAAA;AA8HxD,eAAO,MAAM,KAAK,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAsBA,OAAO,EAIL,KAAK,wBAAwB,EAO7B,KAAK,YAAY,EAEjB,KAAK,UAAU,EAYhB,MAAM,sBAAsB,CAAA;AAa7B,OAAO,EAAC,kBAAkB,EAAc,MAAM,gCAAgC,CAAA;AAI9E,KAAK,KAAK,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,GAAG,MAAM,EAAE,CAAC,CAAA;AA8HxD,eAAO,MAAM,KAAK,07YAyHjB,CAAA;AAmpED;;;;;;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;AAkqCD,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
|
@@ -64,13 +64,13 @@ const isInternalPartExtractorId = (value) => value.trim().includes('_');
|
|
|
64
64
|
const execFileAsync = promisify(execFile);
|
|
65
65
|
export const usage = `AssetHub CLI
|
|
66
66
|
|
|
67
|
-
|
|
67
|
+
CLI and MCP are available to all AssetHub users. Workspace permissions and feature availability apply.
|
|
68
68
|
|
|
69
69
|
Usage:
|
|
70
70
|
assethub --version
|
|
71
71
|
assethub doctor [--mcp] [--profile <name>] [--timeout-ms <n>]
|
|
72
|
-
assethub mcp tools [tool-name] [--profile <name>] [--timeout-ms <n>]
|
|
73
|
-
assethub mcp config --client cursor|codex [--base-url <url>]
|
|
72
|
+
assethub mcp tools [tool-name] [--account] [--profile <name>] [--timeout-ms <n>]
|
|
73
|
+
assethub mcp config --client cursor|codex [--account] [--base-url <url>]
|
|
74
74
|
assethub auth login --api-key <key> [--base-url <url>] [--profile <name>]
|
|
75
75
|
assethub auth login --api-key-stdin [--base-url <url>] [--profile <name>]
|
|
76
76
|
assethub auth login --access-token-stdin [--base-url <url>] [--profile <name>]
|
|
@@ -79,6 +79,10 @@ Usage:
|
|
|
79
79
|
assethub workspace list|get
|
|
80
80
|
assethub workspace create --name <name> [--operation-id <uuid>]
|
|
81
81
|
assethub workspace use <workspace-id>
|
|
82
|
+
assethub workspace members [--workspace <id>]
|
|
83
|
+
assethub workspace invite --email <email> [--role user|admin] [--resend] [--workspace <id>]
|
|
84
|
+
assethub workspace set-role <user-id> --role user|admin [--workspace <id>]
|
|
85
|
+
assethub workspace remove-member <user-id> [--workspace <id>]
|
|
82
86
|
assethub workspace prepare|sync|analyze|verify --internal --manifest <json> --state <json>
|
|
83
87
|
assethub workspace self-check --internal
|
|
84
88
|
assethub workspace context put --internal --org <uuid> --actor <uuid> --canvas <id> --file <json> [--if-version <n>] [--order <uuid>]
|
|
@@ -1248,6 +1252,7 @@ const workspaceAuth = async (flags) => {
|
|
|
1248
1252
|
accessToken,
|
|
1249
1253
|
workspaceMfaToken,
|
|
1250
1254
|
baseUrl,
|
|
1255
|
+
selectedWorkspaceId: environmentToken ? undefined : stored?.workspaceId,
|
|
1251
1256
|
client: createWorkspaceClient({ accessToken, workspaceMfaToken, baseUrl }),
|
|
1252
1257
|
};
|
|
1253
1258
|
};
|
|
@@ -1258,13 +1263,35 @@ const commandWorkspace = async (subcommand, positionals, flags) => {
|
|
|
1258
1263
|
? undefined
|
|
1259
1264
|
: env.ASSETHUB_API_KEY?.trim();
|
|
1260
1265
|
const auth = await workspaceAuth(flags);
|
|
1266
|
+
if (['members', 'invite', 'set-role', 'remove-member'].includes(subcommand ?? '')) {
|
|
1267
|
+
let workspaceId = getFlag(flags, 'workspace') ?? auth.selectedWorkspaceId;
|
|
1268
|
+
if (!workspaceId)
|
|
1269
|
+
workspaceId = (await auth.client.list()).workspaces.find(item => item.active)?.id;
|
|
1270
|
+
if (!workspaceId)
|
|
1271
|
+
throw new Error('Specify --workspace <id> or select one with workspace use <id>');
|
|
1272
|
+
if (subcommand === 'members') {
|
|
1273
|
+
print(await auth.client.listMembers(workspaceId));
|
|
1274
|
+
return;
|
|
1275
|
+
}
|
|
1276
|
+
const role = subcommand === 'invite' ? getFlag(flags, 'role') ?? 'user' : subcommand === 'set-role' ? requireFlag(flags, 'role') : undefined;
|
|
1277
|
+
if (role !== undefined && role !== 'user' && role !== 'admin')
|
|
1278
|
+
throw new Error('--role must be user or admin');
|
|
1279
|
+
stderr.write(`[workspace] ${subcommand} in ${workspaceId}…\n`);
|
|
1280
|
+
if (subcommand === 'invite')
|
|
1281
|
+
print(await auth.client.inviteMember(workspaceId, { email: requireFlag(flags, 'email'), role: role, ...(hasFlag(flags, 'resend') ? { resend: true } : {}) }));
|
|
1282
|
+
else if (subcommand === 'set-role')
|
|
1283
|
+
print(await auth.client.setMemberRole(workspaceId, { userId: requirePositional(positionals, 2, 'user-id'), role: role }));
|
|
1284
|
+
else
|
|
1285
|
+
print(await auth.client.removeMember(workspaceId, requirePositional(positionals, 2, 'user-id')));
|
|
1286
|
+
return;
|
|
1287
|
+
}
|
|
1261
1288
|
if (subcommand === 'list') {
|
|
1262
1289
|
print(await auth.client.list());
|
|
1263
1290
|
return;
|
|
1264
1291
|
}
|
|
1265
1292
|
if (subcommand === 'get') {
|
|
1266
1293
|
const account = await auth.client.list();
|
|
1267
|
-
const selected = auth.
|
|
1294
|
+
const selected = auth.selectedWorkspaceId;
|
|
1268
1295
|
const workspace = account.workspaces.find(item => selected ? item.id === selected : item.active);
|
|
1269
1296
|
if (!workspace)
|
|
1270
1297
|
throw new Error('No workspace selected; use workspace use <id>');
|
|
@@ -3260,7 +3287,13 @@ const run = async () => {
|
|
|
3260
3287
|
if (command === 'mcp' && subcommand === 'tools') {
|
|
3261
3288
|
stderr.write('Discovering AssetHub MCP tools…\n');
|
|
3262
3289
|
const report = await diagnose({
|
|
3263
|
-
resolveAuth: () =>
|
|
3290
|
+
resolveAuth: async () => {
|
|
3291
|
+
if (!hasFlag(parsed.flags, 'account'))
|
|
3292
|
+
return resolveAuth(parsed.flags);
|
|
3293
|
+
const auth = await workspaceAuth(parsed.flags);
|
|
3294
|
+
return { apiKey: auth.accessToken, workspaceMfaToken: auth.workspaceMfaToken, baseUrl: auth.baseUrl, profile: auth.profile, source: 'user' };
|
|
3295
|
+
},
|
|
3296
|
+
account: hasFlag(parsed.flags, 'account'),
|
|
3264
3297
|
includeMcp: true,
|
|
3265
3298
|
includeTools: true,
|
|
3266
3299
|
timeoutMs: parsePositiveIntegerFlag(parsed.flags, 'timeout-ms', 15000),
|
|
@@ -3287,7 +3320,7 @@ const run = async () => {
|
|
|
3287
3320
|
if (command === 'mcp') {
|
|
3288
3321
|
if (subcommand !== 'config')
|
|
3289
3322
|
throw new Error('Use mcp tools [tool-name] or mcp config --client cursor|codex');
|
|
3290
|
-
stdout.write(mcpConfig(requireFlag(parsed.flags, 'client'), getFlag(parsed.flags, 'base-url') ?? env.ASSETHUB_API_BASE_URL ?? defaultBaseUrl));
|
|
3323
|
+
stdout.write(mcpConfig(requireFlag(parsed.flags, 'client'), getFlag(parsed.flags, 'base-url') ?? env.ASSETHUB_API_BASE_URL ?? defaultBaseUrl, hasFlag(parsed.flags, 'account')));
|
|
3291
3324
|
return;
|
|
3292
3325
|
}
|
|
3293
3326
|
if (command === 'doctor') {
|
|
@@ -3319,7 +3352,7 @@ const run = async () => {
|
|
|
3319
3352
|
return;
|
|
3320
3353
|
}
|
|
3321
3354
|
if (command === 'workspace') {
|
|
3322
|
-
if (['list', 'get', 'create', 'use'].includes(subcommand ?? '')) {
|
|
3355
|
+
if (['list', 'get', 'create', 'use', 'members', 'invite', 'set-role', 'remove-member'].includes(subcommand ?? '')) {
|
|
3323
3356
|
await commandWorkspace(subcommand, parsed.positionals, parsed.flags);
|
|
3324
3357
|
return;
|
|
3325
3358
|
}
|
package/dist/setup.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { Tool } from '@modelcontextprotocol/sdk/types.js';
|
|
2
2
|
export declare const cliVersion: () => Promise<string>;
|
|
3
|
-
export declare const mcpConfig: (client: string, baseUrl: string) => string;
|
|
3
|
+
export declare const mcpConfig: (client: string, baseUrl: string, account?: boolean) => string;
|
|
4
4
|
type Check = {
|
|
5
5
|
name: 'api' | 'mcp' | 'configuration';
|
|
6
6
|
status: 'pass' | 'fail';
|
|
@@ -17,12 +17,14 @@ type Auth = {
|
|
|
17
17
|
baseUrl: string;
|
|
18
18
|
profile: string;
|
|
19
19
|
source: string;
|
|
20
|
+
workspaceMfaToken?: string;
|
|
20
21
|
};
|
|
21
|
-
export declare const diagnose: ({ resolveAuth, includeMcp, timeoutMs, includeTools, }: {
|
|
22
|
+
export declare const diagnose: ({ resolveAuth, includeMcp, timeoutMs, includeTools, account, }: {
|
|
22
23
|
resolveAuth: () => Promise<Auth>;
|
|
23
24
|
includeMcp: boolean;
|
|
24
25
|
timeoutMs: number;
|
|
25
26
|
includeTools?: boolean;
|
|
27
|
+
account?: boolean;
|
|
26
28
|
}) => Promise<{
|
|
27
29
|
ok: boolean;
|
|
28
30
|
version: string;
|
package/dist/setup.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"setup.d.ts","sourceRoot":"","sources":["../src/setup.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAC,IAAI,EAAC,MAAM,oCAAoC,CAAA;AAE5D,eAAO,MAAM,UAAU,QAAa,OAAO,CAAC,MAAM,CAKvC,CAAA;AAmBX,eAAO,MAAM,SAAS,GAAI,QAAQ,MAAM,EAAE,SAAS,MAAM,KAAG,
|
|
1
|
+
{"version":3,"file":"setup.d.ts","sourceRoot":"","sources":["../src/setup.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAC,IAAI,EAAC,MAAM,oCAAoC,CAAA;AAE5D,eAAO,MAAM,UAAU,QAAa,OAAO,CAAC,MAAM,CAKvC,CAAA;AAmBX,eAAO,MAAM,SAAS,GAAI,QAAQ,MAAM,EAAE,SAAS,MAAM,EAAE,iBAAe,KAAG,MAsB5E,CAAA;AAED,KAAK,KAAK,GAAG;IACX,IAAI,EAAE,KAAK,GAAG,KAAK,GAAG,eAAe,CAAA;IACrC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAA;IACvB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,KAAK,CAAC,EAAE,IAAI,EAAE,CAAA;CACf,CAAA;AAED,KAAK,IAAI,GAAG;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,iBAAiB,CAAC,EAAE,MAAM,CAAA;CAAC,CAAA;AA2D1G,eAAO,MAAM,QAAQ,GAAU,gEAM5B;IACD,WAAW,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;IAChC,UAAU,EAAE,OAAO,CAAA;IACnB,SAAS,EAAE,MAAM,CAAA;IACjB,YAAY,CAAC,EAAE,OAAO,CAAA;IACtB,OAAO,CAAC,EAAE,OAAO,CAAA;CAClB;;;;;;;;;;;;;;;;;;;;;;EAiHA,CAAA"}
|
package/dist/setup.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { readFile } from 'node:fs/promises';
|
|
2
|
-
import { AssetHubApiError, createAssetHubClient } from '@assethub/api-client';
|
|
2
|
+
import { AssetHubApiError, createAssetHubClient, createWorkspaceClient, WorkspaceClientError } from '@assethub/api-client';
|
|
3
3
|
export const cliVersion = async () => JSON.parse(await readFile(new URL('../package.json', import.meta.url), 'utf8')).version;
|
|
4
4
|
const validatedBaseUrl = (baseUrl) => {
|
|
5
5
|
const url = new URL(baseUrl);
|
|
@@ -11,22 +11,24 @@ const validatedBaseUrl = (baseUrl) => {
|
|
|
11
11
|
throw new Error('Use HTTPS for remote servers; HTTP is supported only on localhost.');
|
|
12
12
|
return url.href.replace(/\/+$/, '');
|
|
13
13
|
};
|
|
14
|
-
export const mcpConfig = (client, baseUrl) => {
|
|
15
|
-
const url = `${validatedBaseUrl(baseUrl)}/api/mcp`;
|
|
14
|
+
export const mcpConfig = (client, baseUrl, account = false) => {
|
|
15
|
+
const url = `${validatedBaseUrl(baseUrl)}${account ? '/api/workspaces/mcp' : '/api/mcp'}`;
|
|
16
|
+
const name = account ? 'assethub-workspaces' : 'assethub';
|
|
17
|
+
const token = account ? 'ASSETHUB_ACCESS_TOKEN' : 'ASSETHUB_API_KEY';
|
|
16
18
|
if (client === 'cursor')
|
|
17
19
|
return (JSON.stringify({
|
|
18
20
|
mcpServers: {
|
|
19
|
-
|
|
21
|
+
[name]: {
|
|
20
22
|
url,
|
|
21
|
-
headers: { Authorization:
|
|
23
|
+
headers: { Authorization: `Bearer \${env:${token}}`, ...(account ? { Cookie: '${env:ASSETHUB_WORKSPACE_MFA_COOKIE}' } : {}) },
|
|
22
24
|
},
|
|
23
25
|
},
|
|
24
26
|
}, null, 2) + '\n');
|
|
25
27
|
if (client === 'codex')
|
|
26
|
-
return `[mcp_servers
|
|
28
|
+
return `[mcp_servers.${name}]\nurl = ${JSON.stringify(url)}\nbearer_token_env_var = "${token}"\n${account ? 'env_http_headers = { Cookie = "ASSETHUB_WORKSPACE_MFA_COOKIE" }\n' : ''}`;
|
|
27
29
|
throw new Error('Use mcp config --client cursor|codex');
|
|
28
30
|
};
|
|
29
|
-
const failedCheck = (name, status, timedOut) => {
|
|
31
|
+
const failedCheck = (name, status, timedOut, account = false) => {
|
|
30
32
|
if (timedOut)
|
|
31
33
|
return {
|
|
32
34
|
name,
|
|
@@ -40,8 +42,8 @@ const failedCheck = (name, status, timedOut) => {
|
|
|
40
42
|
name,
|
|
41
43
|
status: 'fail',
|
|
42
44
|
code: 'UNAUTHORIZED',
|
|
43
|
-
message: 'The API key was rejected.',
|
|
44
|
-
hint: 'Run assethub auth login --api-key-stdin with a current workspace key.',
|
|
45
|
+
message: account ? 'The user access token was rejected.' : 'The API key was rejected.',
|
|
46
|
+
hint: account ? 'Run assethub auth login --access-token-stdin with a current user token.' : 'Run assethub auth login --api-key-stdin with a current workspace key.',
|
|
45
47
|
};
|
|
46
48
|
if (status === 403)
|
|
47
49
|
return {
|
|
@@ -57,7 +59,7 @@ const failedCheck = (name, status, timedOut) => {
|
|
|
57
59
|
status: 'fail',
|
|
58
60
|
code: 'MCP_UNAVAILABLE',
|
|
59
61
|
message: 'Hosted MCP is unavailable for this account or API origin.',
|
|
60
|
-
hint: '
|
|
62
|
+
hint: 'Check the API origin and service status, then retry the MCP connection.',
|
|
61
63
|
};
|
|
62
64
|
if (status === 429)
|
|
63
65
|
return {
|
|
@@ -77,7 +79,7 @@ const failedCheck = (name, status, timedOut) => {
|
|
|
77
79
|
hint: 'Check the API origin, network, and service status; then retry.',
|
|
78
80
|
};
|
|
79
81
|
};
|
|
80
|
-
export const diagnose = async ({ resolveAuth, includeMcp, timeoutMs, includeTools = false, }) => {
|
|
82
|
+
export const diagnose = async ({ resolveAuth, includeMcp, timeoutMs, includeTools = false, account = false, }) => {
|
|
81
83
|
const version = await cliVersion();
|
|
82
84
|
let auth;
|
|
83
85
|
try {
|
|
@@ -110,6 +112,10 @@ export const diagnose = async ({ resolveAuth, includeMcp, timeoutMs, includeTool
|
|
|
110
112
|
});
|
|
111
113
|
const apiCheck = async () => {
|
|
112
114
|
try {
|
|
115
|
+
if (account) {
|
|
116
|
+
await createWorkspaceClient({ accessToken: auth.apiKey, workspaceMfaToken: auth.workspaceMfaToken, baseUrl: auth.baseUrl, fetch: boundedFetch }).list();
|
|
117
|
+
return { name: 'api', status: 'pass' };
|
|
118
|
+
}
|
|
113
119
|
const capabilities = await createAssetHubClient({
|
|
114
120
|
apiKey: auth.apiKey,
|
|
115
121
|
baseUrl: auth.baseUrl,
|
|
@@ -125,7 +131,7 @@ export const diagnose = async ({ resolveAuth, includeMcp, timeoutMs, includeTool
|
|
|
125
131
|
};
|
|
126
132
|
}
|
|
127
133
|
catch (error) {
|
|
128
|
-
return failedCheck('api', error instanceof AssetHubApiError ? error.status : undefined, signal.aborted);
|
|
134
|
+
return failedCheck('api', error instanceof AssetHubApiError || error instanceof WorkspaceClientError ? error.status : undefined, signal.aborted, account);
|
|
129
135
|
}
|
|
130
136
|
};
|
|
131
137
|
const mcpCheck = async () => {
|
|
@@ -133,9 +139,9 @@ export const diagnose = async ({ resolveAuth, includeMcp, timeoutMs, includeTool
|
|
|
133
139
|
const { StreamableHTTPClientTransport, StreamableHTTPError } = await import('@modelcontextprotocol/sdk/client/streamableHttp.js');
|
|
134
140
|
const client = new Client({ name: 'assethub-cli-doctor', version });
|
|
135
141
|
try {
|
|
136
|
-
await client.connect(new StreamableHTTPClientTransport(new URL(`${auth.baseUrl}/api/mcp`), {
|
|
142
|
+
await client.connect(new StreamableHTTPClientTransport(new URL(`${auth.baseUrl}${account ? '/api/workspaces/mcp' : '/api/mcp'}`), {
|
|
137
143
|
fetch: boundedFetch,
|
|
138
|
-
requestInit: { headers: { Authorization: `Bearer ${auth.apiKey}` } },
|
|
144
|
+
requestInit: { headers: { Authorization: `Bearer ${auth.apiKey}`, ...(account && auth.workspaceMfaToken ? { Cookie: `ah_workspace_mfa=${encodeURIComponent(auth.workspaceMfaToken)}` } : {}) } },
|
|
139
145
|
}), { signal, timeout: timeoutMs });
|
|
140
146
|
let toolCount = 0;
|
|
141
147
|
const tools = [];
|
|
@@ -160,7 +166,7 @@ export const diagnose = async ({ resolveAuth, includeMcp, timeoutMs, includeTool
|
|
|
160
166
|
return { name: 'mcp', status: 'pass', toolCount, ...(includeTools ? { tools } : {}) };
|
|
161
167
|
}
|
|
162
168
|
catch (error) {
|
|
163
|
-
return failedCheck('mcp', error instanceof StreamableHTTPError ? error.code : undefined, signal.aborted);
|
|
169
|
+
return failedCheck('mcp', error instanceof StreamableHTTPError ? error.code : undefined, signal.aborted, account);
|
|
164
170
|
}
|
|
165
171
|
finally {
|
|
166
172
|
await client.close();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@assethub/cli",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.14",
|
|
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.7",
|
|
34
34
|
"@modelcontextprotocol/sdk": "^1.30.0"
|
|
35
35
|
},
|
|
36
36
|
"repository": {
|