@meshy-ai/cli 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.env.example +8 -2
- package/README.md +342 -108
- package/dist/client/endpoints/animation-catalog.d.ts +37 -0
- package/dist/client/endpoints/animation-catalog.d.ts.map +1 -0
- package/dist/client/endpoints/animation-catalog.js +55 -0
- package/dist/client/endpoints/animation-catalog.js.map +1 -0
- package/dist/client/endpoints/balance.d.ts +5 -0
- package/dist/client/endpoints/balance.d.ts.map +1 -1
- package/dist/client/endpoints/balance.js +5 -1
- package/dist/client/endpoints/balance.js.map +1 -1
- package/dist/client/endpoints/base.d.ts +41 -7
- package/dist/client/endpoints/base.d.ts.map +1 -1
- package/dist/client/endpoints/base.js +61 -40
- package/dist/client/endpoints/base.js.map +1 -1
- package/dist/client/endpoints/showcases.d.ts +31 -0
- package/dist/client/endpoints/showcases.d.ts.map +1 -0
- package/dist/client/endpoints/showcases.js +49 -0
- package/dist/client/endpoints/showcases.js.map +1 -0
- package/dist/client/errors.d.ts +1 -0
- package/dist/client/errors.d.ts.map +1 -1
- package/dist/client/errors.js +1 -1
- package/dist/client/errors.js.map +1 -1
- package/dist/client/index.d.ts +47 -38
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +89 -120
- package/dist/client/index.js.map +1 -1
- package/dist/client/resource-registry.d.ts +97 -0
- package/dist/client/resource-registry.d.ts.map +1 -0
- package/dist/client/resource-registry.js +157 -0
- package/dist/client/resource-registry.js.map +1 -0
- package/dist/client/transport.d.ts +99 -0
- package/dist/client/transport.d.ts.map +1 -0
- package/dist/client/transport.js +320 -0
- package/dist/client/transport.js.map +1 -0
- package/dist/client/types.d.ts +17 -6
- package/dist/client/types.d.ts.map +1 -1
- package/dist/client/types.js +28 -6
- package/dist/client/types.js.map +1 -1
- package/dist/cmd/animation-catalog.d.ts +26 -0
- package/dist/cmd/animation-catalog.d.ts.map +1 -0
- package/dist/cmd/animation-catalog.js +80 -0
- package/dist/cmd/animation-catalog.js.map +1 -0
- package/dist/cmd/api.d.ts +3 -2
- package/dist/cmd/api.d.ts.map +1 -1
- package/dist/cmd/api.js +22 -8
- package/dist/cmd/api.js.map +1 -1
- package/dist/cmd/auth.d.ts.map +1 -1
- package/dist/cmd/auth.js +5 -0
- package/dist/cmd/auth.js.map +1 -1
- package/dist/cmd/balance.d.ts.map +1 -1
- package/dist/cmd/balance.js +10 -6
- package/dist/cmd/balance.js.map +1 -1
- package/dist/cmd/creative-lab.d.ts +26 -0
- package/dist/cmd/creative-lab.d.ts.map +1 -0
- package/dist/cmd/creative-lab.js +256 -0
- package/dist/cmd/creative-lab.js.map +1 -0
- package/dist/cmd/delete.d.ts.map +1 -1
- package/dist/cmd/delete.js +6 -7
- package/dist/cmd/delete.js.map +1 -1
- package/dist/cmd/doctor.d.ts +23 -0
- package/dist/cmd/doctor.d.ts.map +1 -0
- package/dist/cmd/doctor.js +61 -0
- package/dist/cmd/doctor.js.map +1 -0
- package/dist/cmd/download.d.ts +17 -0
- package/dist/cmd/download.d.ts.map +1 -0
- package/dist/cmd/download.js +436 -0
- package/dist/cmd/download.js.map +1 -0
- package/dist/cmd/inspect.d.ts +63 -0
- package/dist/cmd/inspect.d.ts.map +1 -0
- package/dist/cmd/inspect.js +179 -0
- package/dist/cmd/inspect.js.map +1 -0
- package/dist/cmd/make.d.ts +13 -3
- package/dist/cmd/make.d.ts.map +1 -1
- package/dist/cmd/make.js +240 -36
- package/dist/cmd/make.js.map +1 -1
- package/dist/cmd/mesh.d.ts +13 -0
- package/dist/cmd/mesh.d.ts.map +1 -0
- package/dist/cmd/mesh.js +67 -0
- package/dist/cmd/mesh.js.map +1 -0
- package/dist/cmd/project.d.ts +16 -0
- package/dist/cmd/project.d.ts.map +1 -0
- package/dist/cmd/project.js +136 -0
- package/dist/cmd/project.js.map +1 -0
- package/dist/cmd/resources.d.ts +5 -0
- package/dist/cmd/resources.d.ts.map +1 -1
- package/dist/cmd/resources.js +38 -10
- package/dist/cmd/resources.js.map +1 -1
- package/dist/cmd/showcases.d.ts +10 -0
- package/dist/cmd/showcases.d.ts.map +1 -0
- package/dist/cmd/showcases.js +63 -0
- package/dist/cmd/showcases.js.map +1 -0
- package/dist/cmd/slicer.d.ts +12 -0
- package/dist/cmd/slicer.d.ts.map +1 -0
- package/dist/cmd/slicer.js +46 -0
- package/dist/cmd/slicer.js.map +1 -0
- package/dist/cmd/uv-unwrap.d.ts +16 -0
- package/dist/cmd/uv-unwrap.d.ts.map +1 -0
- package/dist/cmd/uv-unwrap.js +52 -0
- package/dist/cmd/uv-unwrap.js.map +1 -0
- package/dist/index.d.ts +13 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +141 -8
- package/dist/index.js.map +1 -1
- package/dist/internal/artifacts.d.ts +97 -0
- package/dist/internal/artifacts.d.ts.map +1 -0
- package/dist/internal/artifacts.js +280 -0
- package/dist/internal/artifacts.js.map +1 -0
- package/dist/internal/atomic-file.d.ts +39 -0
- package/dist/internal/atomic-file.d.ts.map +1 -0
- package/dist/internal/atomic-file.js +160 -0
- package/dist/internal/atomic-file.js.map +1 -0
- package/dist/internal/command-helpers.d.ts +46 -0
- package/dist/internal/command-helpers.d.ts.map +1 -0
- package/dist/internal/command-helpers.js +61 -0
- package/dist/internal/command-helpers.js.map +1 -0
- package/dist/internal/config.d.ts +48 -5
- package/dist/internal/config.d.ts.map +1 -1
- package/dist/internal/config.js +95 -6
- package/dist/internal/config.js.map +1 -1
- package/dist/internal/context.d.ts +25 -0
- package/dist/internal/context.d.ts.map +1 -0
- package/dist/internal/context.js +37 -0
- package/dist/internal/context.js.map +1 -0
- package/dist/internal/credentials.d.ts +11 -0
- package/dist/internal/credentials.d.ts.map +1 -1
- package/dist/internal/credentials.js +2 -0
- package/dist/internal/credentials.js.map +1 -1
- package/dist/internal/doctor.d.ts +94 -0
- package/dist/internal/doctor.d.ts.map +1 -0
- package/dist/internal/doctor.js +280 -0
- package/dist/internal/doctor.js.map +1 -0
- package/dist/internal/download.d.ts +147 -13
- package/dist/internal/download.d.ts.map +1 -1
- package/dist/internal/download.js +735 -142
- package/dist/internal/download.js.map +1 -1
- package/dist/internal/env-file.d.ts +29 -0
- package/dist/internal/env-file.d.ts.map +1 -0
- package/dist/internal/env-file.js +95 -0
- package/dist/internal/env-file.js.map +1 -0
- package/dist/internal/errors.d.ts +74 -1
- package/dist/internal/errors.d.ts.map +1 -1
- package/dist/internal/errors.js +173 -1
- package/dist/internal/errors.js.map +1 -1
- package/dist/internal/file-input.d.ts +52 -12
- package/dist/internal/file-input.d.ts.map +1 -1
- package/dist/internal/file-input.js +162 -33
- package/dist/internal/file-input.js.map +1 -1
- package/dist/internal/global-options.d.ts +6 -4
- package/dist/internal/global-options.d.ts.map +1 -1
- package/dist/internal/global-options.js +19 -4
- package/dist/internal/global-options.js.map +1 -1
- package/dist/internal/inspect.d.ts +67 -0
- package/dist/internal/inspect.d.ts.map +1 -0
- package/dist/internal/inspect.js +111 -0
- package/dist/internal/inspect.js.map +1 -0
- package/dist/internal/lock.d.ts +19 -0
- package/dist/internal/lock.d.ts.map +1 -0
- package/dist/internal/lock.js +66 -0
- package/dist/internal/lock.js.map +1 -0
- package/dist/internal/material-links.d.ts +115 -0
- package/dist/internal/material-links.d.ts.map +1 -0
- package/dist/internal/material-links.js +577 -0
- package/dist/internal/material-links.js.map +1 -0
- package/dist/internal/obj-transform.d.ts +115 -0
- package/dist/internal/obj-transform.d.ts.map +1 -0
- package/dist/internal/obj-transform.js +649 -0
- package/dist/internal/obj-transform.js.map +1 -0
- package/dist/internal/operation-store.d.ts +123 -0
- package/dist/internal/operation-store.d.ts.map +1 -0
- package/dist/internal/operation-store.js +229 -0
- package/dist/internal/operation-store.js.map +1 -0
- package/dist/internal/output.d.ts +20 -2
- package/dist/internal/output.d.ts.map +1 -1
- package/dist/internal/output.js +32 -4
- package/dist/internal/output.js.map +1 -1
- package/dist/internal/paths.d.ts +89 -0
- package/dist/internal/paths.d.ts.map +1 -0
- package/dist/internal/paths.js +168 -0
- package/dist/internal/paths.js.map +1 -0
- package/dist/internal/payload.d.ts +15 -0
- package/dist/internal/payload.d.ts.map +1 -1
- package/dist/internal/payload.js +50 -3
- package/dist/internal/payload.js.map +1 -1
- package/dist/internal/poll.d.ts +30 -4
- package/dist/internal/poll.d.ts.map +1 -1
- package/dist/internal/poll.js +99 -16
- package/dist/internal/poll.js.map +1 -1
- package/dist/internal/project-store.d.ts +197 -0
- package/dist/internal/project-store.d.ts.map +1 -0
- package/dist/internal/project-store.js +467 -0
- package/dist/internal/project-store.js.map +1 -0
- package/dist/internal/result.d.ts +50 -0
- package/dist/internal/result.d.ts.map +1 -0
- package/dist/internal/result.js +41 -0
- package/dist/internal/result.js.map +1 -0
- package/dist/internal/runtime.d.ts +35 -5
- package/dist/internal/runtime.d.ts.map +1 -1
- package/dist/internal/runtime.js +68 -18
- package/dist/internal/runtime.js.map +1 -1
- package/dist/internal/slicers.d.ts +117 -0
- package/dist/internal/slicers.d.ts.map +1 -0
- package/dist/internal/slicers.js +314 -0
- package/dist/internal/slicers.js.map +1 -0
- package/dist/internal/stream.d.ts +58 -0
- package/dist/internal/stream.d.ts.map +1 -0
- package/dist/internal/stream.js +280 -0
- package/dist/internal/stream.js.map +1 -0
- package/dist/internal/task-command.d.ts +128 -11
- package/dist/internal/task-command.d.ts.map +1 -1
- package/dist/internal/task-command.js +991 -111
- package/dist/internal/task-command.js.map +1 -1
- package/dist/internal/task-view.d.ts +56 -0
- package/dist/internal/task-view.d.ts.map +1 -0
- package/dist/internal/task-view.js +95 -0
- package/dist/internal/task-view.js.map +1 -0
- package/dist/internal/update-notifier.d.ts +5 -1
- package/dist/internal/update-notifier.d.ts.map +1 -1
- package/dist/internal/update-notifier.js +7 -3
- package/dist/internal/update-notifier.js.map +1 -1
- package/dist/root.d.ts +10 -0
- package/dist/root.d.ts.map +1 -1
- package/dist/root.js +75 -10
- package/dist/root.js.map +1 -1
- package/package.json +3 -2
- package/skills/meshy-cli/SKILL.md +140 -59
- package/dist/client/endpoints/analyze-printability.d.ts +0 -5
- package/dist/client/endpoints/analyze-printability.d.ts.map +0 -1
- package/dist/client/endpoints/analyze-printability.js +0 -7
- package/dist/client/endpoints/analyze-printability.js.map +0 -1
- package/dist/client/endpoints/animate.d.ts +0 -6
- package/dist/client/endpoints/animate.d.ts.map +0 -1
- package/dist/client/endpoints/animate.js +0 -8
- package/dist/client/endpoints/animate.js.map +0 -1
- package/dist/client/endpoints/convert.d.ts +0 -5
- package/dist/client/endpoints/convert.d.ts.map +0 -1
- package/dist/client/endpoints/convert.js +0 -7
- package/dist/client/endpoints/convert.js.map +0 -1
- package/dist/client/endpoints/image-to-3d.d.ts +0 -5
- package/dist/client/endpoints/image-to-3d.d.ts.map +0 -1
- package/dist/client/endpoints/image-to-3d.js +0 -7
- package/dist/client/endpoints/image-to-3d.js.map +0 -1
- package/dist/client/endpoints/image-to-image.d.ts +0 -5
- package/dist/client/endpoints/image-to-image.d.ts.map +0 -1
- package/dist/client/endpoints/image-to-image.js +0 -7
- package/dist/client/endpoints/image-to-image.js.map +0 -1
- package/dist/client/endpoints/multi-color-print.d.ts +0 -5
- package/dist/client/endpoints/multi-color-print.d.ts.map +0 -1
- package/dist/client/endpoints/multi-color-print.js +0 -7
- package/dist/client/endpoints/multi-color-print.js.map +0 -1
- package/dist/client/endpoints/multi-image-to-3d.d.ts +0 -5
- package/dist/client/endpoints/multi-image-to-3d.d.ts.map +0 -1
- package/dist/client/endpoints/multi-image-to-3d.js +0 -7
- package/dist/client/endpoints/multi-image-to-3d.js.map +0 -1
- package/dist/client/endpoints/remesh.d.ts +0 -5
- package/dist/client/endpoints/remesh.d.ts.map +0 -1
- package/dist/client/endpoints/remesh.js +0 -7
- package/dist/client/endpoints/remesh.js.map +0 -1
- package/dist/client/endpoints/repair-printability.d.ts +0 -5
- package/dist/client/endpoints/repair-printability.d.ts.map +0 -1
- package/dist/client/endpoints/repair-printability.js +0 -7
- package/dist/client/endpoints/repair-printability.js.map +0 -1
- package/dist/client/endpoints/resize.d.ts +0 -5
- package/dist/client/endpoints/resize.d.ts.map +0 -1
- package/dist/client/endpoints/resize.js +0 -7
- package/dist/client/endpoints/resize.js.map +0 -1
- package/dist/client/endpoints/retexture.d.ts +0 -5
- package/dist/client/endpoints/retexture.d.ts.map +0 -1
- package/dist/client/endpoints/retexture.js +0 -7
- package/dist/client/endpoints/retexture.js.map +0 -1
- package/dist/client/endpoints/rigging.d.ts +0 -6
- package/dist/client/endpoints/rigging.d.ts.map +0 -1
- package/dist/client/endpoints/rigging.js +0 -8
- package/dist/client/endpoints/rigging.js.map +0 -1
- package/dist/client/endpoints/text-to-3d.d.ts +0 -6
- package/dist/client/endpoints/text-to-3d.d.ts.map +0 -1
- package/dist/client/endpoints/text-to-3d.js +0 -8
- package/dist/client/endpoints/text-to-3d.js.map +0 -1
- package/dist/client/endpoints/text-to-image.d.ts +0 -5
- package/dist/client/endpoints/text-to-image.d.ts.map +0 -1
- package/dist/client/endpoints/text-to-image.js +0 -7
- package/dist/client/endpoints/text-to-image.js.map +0 -1
- package/dist/client/endpoints/text-to-motion.d.ts +0 -6
- package/dist/client/endpoints/text-to-motion.d.ts.map +0 -1
- package/dist/client/endpoints/text-to-motion.js +0 -8
- package/dist/client/endpoints/text-to-motion.js.map +0 -1
package/README.md
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
# meshy-cli
|
|
2
2
|
|
|
3
|
-
A small, well-structured command-line interface for the [Meshy AI API](https://docs.meshy.ai/) — text-to-3D, image-to-3D (standard and smart-topology), text-to-motion, remesh, convert, resize, rigging, animation, retexture, 2D image generation, multi-color print output, and the `balance` endpoint. Built for humans and AI agents.
|
|
3
|
+
A small, well-structured command-line interface for the [Meshy AI API](https://docs.meshy.ai/) — text-to-3D, image-to-3D (standard and smart-topology), text-to-motion, remesh, convert, resize, UV unwrap, rigging, animation, retexture, 2D image generation, multi-color print output, Creative Lab products, the public animation catalog, Enterprise showcases, and the `balance` endpoint — plus the local helpers a 3D-printing or agent workflow needs (selective downloads, project folders, face-count checks, OBJ print preparation, slicer launch, environment diagnosis). Built for humans and AI agents.
|
|
4
4
|
|
|
5
5
|
Two layers. `meshy make` chains the documented flows so that one command
|
|
6
6
|
produces one model. Underneath, a per-endpoint command for every resource
|
|
7
|
-
shares a uniform `create / get / list / wait / delete` verb surface, with a raw
|
|
7
|
+
shares a uniform `create / get / list / wait / stream / delete` verb surface, with a raw
|
|
8
8
|
`api` passthrough for endpoints the CLI doesn't model yet and a `skills/`
|
|
9
9
|
directory of agent-facing documentation.
|
|
10
10
|
|
|
@@ -12,11 +12,12 @@ The flag surface is deliberately curated rather than a 1:1 mirror of the API: de
|
|
|
12
12
|
|
|
13
13
|
## Install
|
|
14
14
|
|
|
15
|
-
Requires Node 24+.
|
|
15
|
+
Requires Node 24+. No Python, no other runtime.
|
|
16
16
|
|
|
17
17
|
```bash
|
|
18
18
|
npm i -g meshy-cli # installs `meshy-cli` and `meshy`
|
|
19
19
|
meshy --help
|
|
20
|
+
meshy doctor # local diagnosis: versions, credential sources, base URLs (no network)
|
|
20
21
|
```
|
|
21
22
|
|
|
22
23
|
The same build is also published under the scoped alias
|
|
@@ -35,6 +36,7 @@ pnpm install
|
|
|
35
36
|
pnpm build
|
|
36
37
|
node dist/index.js --help
|
|
37
38
|
pnpm link --global # exposes `meshy` / `meshy-cli` on $PATH
|
|
39
|
+
pnpm typecheck && pnpm test # `pnpm test` rebuilds dist first (subprocess tests run it)
|
|
38
40
|
```
|
|
39
41
|
|
|
40
42
|
## Auth
|
|
@@ -61,22 +63,32 @@ Or keep it in the environment — unchanged, and still the right choice for CI:
|
|
|
61
63
|
```bash
|
|
62
64
|
export MESHY_API_KEY=msy_your_key_here
|
|
63
65
|
meshy-cli --api-key msy_... balance # or per-call
|
|
66
|
+
meshy balance --api-key-file ./keys.env # dotenv-style file; only MESHY_API_KEY is read
|
|
64
67
|
```
|
|
65
68
|
|
|
66
69
|
Get a key at <https://www.meshy.ai/settings/api>.
|
|
67
70
|
|
|
68
|
-
**Resolution order:** `--api-key` › `MESHY_API_KEY` › the active stored profile.
|
|
71
|
+
**Resolution order:** `--api-key` › `MESHY_API_KEY` › `--api-key-file` › the active stored profile.
|
|
69
72
|
The environment variable stays ahead of the stored credential on purpose, so a
|
|
70
73
|
CI runner is never overridden by whatever a developer once logged into on that
|
|
71
|
-
machine. With none of the
|
|
72
|
-
fixes it.
|
|
74
|
+
machine. With none of the four, commands exit `3` and print the command that
|
|
75
|
+
fixes it. An empty or placeholder `--api-key` / `MESHY_API_KEY` counts as unset.
|
|
76
|
+
|
|
77
|
+
**`--api-key-file`** reads exactly one variable, `MESHY_API_KEY`, from a
|
|
78
|
+
dotenv-style file (`export` prefix, quotes and `#` comments accepted; nothing is
|
|
79
|
+
expanded or executed, other keys are ignored). A file you name but that is
|
|
80
|
+
missing, malformed or key-less is an error — never a silent fall-through to
|
|
81
|
+
another account. There is no automatic `.env` discovery. The flag is not called
|
|
82
|
+
`--env-file` because Node.js itself intercepts that name anywhere in argv and
|
|
83
|
+
loads the whole file into the environment before the CLI starts.
|
|
73
84
|
|
|
74
85
|
**Where it lives:** `~/.config/meshy/credentials.json`, mode `0600`, on every
|
|
75
86
|
platform (`MESHY_CONFIG_DIR` or `MESHY_CREDENTIALS_PATH` move it). Writes go
|
|
76
87
|
through a cross-process lock and a temp-file rename, because several agents
|
|
77
88
|
driving this CLI at once is the normal case. A non-production `--base-url-v1`
|
|
78
89
|
reads and writes `credentials.dev.json` instead, so staging cannot clobber a
|
|
79
|
-
production login.
|
|
90
|
+
production login. Stored profiles are only ever sent to the v1/v2 origins they
|
|
91
|
+
were resolved for (and to a Creative Lab base on the same origin).
|
|
80
92
|
|
|
81
93
|
**OAuth token refresh:** when the stored OAuth access token is within 60 seconds
|
|
82
94
|
of expiry (or already expired), the CLI silently refreshes it using the stored
|
|
@@ -105,13 +117,16 @@ opinions spends someone else's credits. Compose anything else from the resource
|
|
|
105
117
|
commands below.
|
|
106
118
|
|
|
107
119
|
```bash
|
|
108
|
-
meshy make "a red sports car" --dry-run
|
|
109
|
-
meshy make "a red sports car" --max-credits 25
|
|
120
|
+
meshy make "a red sports car" --dry-run # the steps and the estimate, no spend, no network
|
|
121
|
+
meshy make "a red sports car" --max-credits 25 # refuse to start when over budget
|
|
122
|
+
meshy make "a red sports car" --async # submit step 1 (one POST), return its id + pending_steps
|
|
123
|
+
meshy make "a red sports car" --stop-after-first # wait for step 1, then return the resume command
|
|
110
124
|
```
|
|
111
125
|
|
|
112
|
-
|
|
113
|
-
error's
|
|
114
|
-
beats starting over, which would pay for
|
|
126
|
+
All guards run before the first task is created. If a later step fails, the
|
|
127
|
+
error carries the finished step's task id and the command that resumes from it —
|
|
128
|
+
running that beats starting over, which would pay for the finished step twice.
|
|
129
|
+
`--async` and `--stop-after-first` are mutually exclusive.
|
|
115
130
|
|
|
116
131
|
## At a glance
|
|
117
132
|
|
|
@@ -128,34 +143,140 @@ meshy-cli image-to-3d create --image-url https://example.com/cat.png
|
|
|
128
143
|
|
|
129
144
|
# text → standalone motion clip (Prime/FBX by default; Swift produces BVH)
|
|
130
145
|
meshy-cli text-to-motion create --prompt "a character waving" --duration 3
|
|
131
|
-
meshy-cli text-to-motion create --prompt "a quick dodge to the left" --duration 2.5 --mode swift
|
|
132
146
|
|
|
133
147
|
# smart topology: component-aware low-poly with a native polycount
|
|
134
148
|
meshy-cli image-to-3d create --image-url cat.png --model-type smart-topology --target-polycount 10000
|
|
135
149
|
|
|
136
|
-
#
|
|
137
|
-
meshy-cli
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
meshy-cli
|
|
141
|
-
|
|
142
|
-
#
|
|
143
|
-
|
|
144
|
-
meshy-
|
|
145
|
-
meshy
|
|
150
|
+
# fire-and-forget (--async): exactly one POST, returns the task_id, query later
|
|
151
|
+
TASK=$(meshy-cli text-to-image create --prompt "mountain landscape" --async --output-schema v1 | jq -r .result.submission.task_id)
|
|
152
|
+
meshy-cli text-to-image get "$TASK" --output-schema v1
|
|
153
|
+
meshy-cli text-to-image wait "$TASK" --output-schema v1 --save-json ./task.json
|
|
154
|
+
meshy-cli text-to-image stream "$TASK" --format ndjson --output-schema v1 # Server-Sent Events
|
|
155
|
+
|
|
156
|
+
# UV unwrap and Creative Lab (photo → printable product, two stages)
|
|
157
|
+
meshy uv-unwrap create --input-task-id <id> --async
|
|
158
|
+
meshy creative-lab figure prototype create --image-url ./photo.png --name demo --async
|
|
159
|
+
meshy creative-lab figure build create --input-task-id <prototype-id> --async
|
|
160
|
+
meshy creative-lab lamp build create --input-task-id <id> --model-format zip --options '{"diameter_mm":180}'
|
|
161
|
+
|
|
162
|
+
# public animation catalog (no key) and Enterprise showcases (billed per request)
|
|
163
|
+
meshy animation-catalog list --category DailyActions --search wave
|
|
164
|
+
meshy showcases list --search car --page-size 3 --model-format glb
|
|
165
|
+
|
|
166
|
+
# local helpers (no key, no network)
|
|
167
|
+
meshy download --task-json ./task.json --asset result.basic_animations.walking_glb_url --output walking.glb
|
|
168
|
+
meshy project init --root ./meshy_output --name demo
|
|
169
|
+
meshy inspect faces --task-json ./task.json --max-faces 300000
|
|
170
|
+
meshy mesh prepare-print ./model.obj --height-mm 75
|
|
171
|
+
meshy slicer detect
|
|
172
|
+
meshy doctor
|
|
146
173
|
|
|
147
174
|
# raw passthrough for any endpoint
|
|
148
175
|
meshy-cli api GET /balance
|
|
149
176
|
meshy-cli api POST /text-to-3d --data '{"mode":"preview","prompt":"a cactus"}'
|
|
150
177
|
```
|
|
151
178
|
|
|
179
|
+
## Stable machine output: `--output-schema v1`
|
|
180
|
+
|
|
181
|
+
Existing commands keep their 0.2.0 output (`legacy`) unless told otherwise; the
|
|
182
|
+
commands added in this release always speak `v1`. Pass `--output-schema v1` to
|
|
183
|
+
get one envelope with six fixed keys on stdout, in `json` (default), `pretty`
|
|
184
|
+
or `ndjson`:
|
|
185
|
+
|
|
186
|
+
```json
|
|
187
|
+
{
|
|
188
|
+
"schema_version": "meshy.cli/v1",
|
|
189
|
+
"command": "image-to-3d.get",
|
|
190
|
+
"ok": true,
|
|
191
|
+
"result": {
|
|
192
|
+
"task": { "task_id": "…", "resource": "image-to-3d", "status": "IN_PROGRESS", "progress": 52,
|
|
193
|
+
"face_count": null, "consumed_credits": null, "model_urls": {}, "task_error": null, "…": "…" },
|
|
194
|
+
"submission": { "state": "accepted", "operation_id": null },
|
|
195
|
+
"downloads": { "state": "not_requested", "files": [], "metadata_path": null },
|
|
196
|
+
"saved_json": null
|
|
197
|
+
},
|
|
198
|
+
"error": null,
|
|
199
|
+
"warnings": []
|
|
200
|
+
}
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
`ok` says whether the CLI operation completed; `result.task.status` is the
|
|
204
|
+
server's task state. A `get` of a FAILED task is `ok:true` (the query worked);
|
|
205
|
+
a `wait` that ends on FAILED is `ok:false` with the whole task kept in `result`.
|
|
206
|
+
Fields the server did not send are `null` — a missing `face_count` is never `0`.
|
|
207
|
+
`--include-raw` adds the untouched response under `result.task.raw`;
|
|
208
|
+
`--save-json <file>` writes the raw API JSON (never the envelope) and refuses to
|
|
209
|
+
overwrite. Progress and update notices go to stderr, so stdout is always exactly
|
|
210
|
+
one JSON document (`ndjson` streams emit one line per event plus a final
|
|
211
|
+
`outcome` line). Errors are envelopes too:
|
|
212
|
+
|
|
213
|
+
```json
|
|
214
|
+
{ "schema_version": "meshy.cli/v1", "command": "text-to-3d.create", "ok": false,
|
|
215
|
+
"result": { "submission": { "state": "unknown", "operation_id": "…" }, "task": null },
|
|
216
|
+
"error": { "code": "submission_unknown", "message": "…", "http_status": null, "retryable": false,
|
|
217
|
+
"recovery": { "action": "reconcile", "automatic": false, "command": "meshy text-to-3d list …" } },
|
|
218
|
+
"warnings": [] }
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
### Create, wait, stream and money
|
|
222
|
+
|
|
223
|
+
- `create` sends **exactly one POST**, journaled locally before it leaves
|
|
224
|
+
(`~/.config/meshy/operations/<operation-id>.json`, no key material). A lost
|
|
225
|
+
response, a 5xx or a malformed success is `submission_unknown` (exit 10): the
|
|
226
|
+
server may have created the task, so the CLI never retries and never suggests
|
|
227
|
+
re-running the create. Reconcile with `list`, then decide.
|
|
228
|
+
- `--operation-id <id>` replays the recorded outcome of an identical earlier
|
|
229
|
+
request instead of submitting again; a different request under the same id is
|
|
230
|
+
refused (`operation_conflict`, exit 2, naming what differs). "Identical" means
|
|
231
|
+
the same resource, API origin, credential — a one-way digest of the API key,
|
|
232
|
+
or the OAuth account (its user id, else the login id `meshy auth login` mints
|
|
233
|
+
for the profile) — and payload, with every inline image or model hashed by
|
|
234
|
+
content. An OAuth profile saved before login ids existed carries no verifiable
|
|
235
|
+
identity: it can start operations but is refused a replay (exit 2,
|
|
236
|
+
`credential_unverified`) until you log in again. This is a local record, not a
|
|
237
|
+
server-side idempotency key.
|
|
238
|
+
- Local targets that would fail after the POST are checked before it: an
|
|
239
|
+
existing `--save-json` file, an `-o` path outside `--workspace`, a missing
|
|
240
|
+
`--project` all exit 11 with "nothing was submitted" and cost no request.
|
|
241
|
+
- Once the server has accepted a task, every later failure — saving JSON,
|
|
242
|
+
polling (a 503), downloading, recording, Ctrl-C — still reports
|
|
243
|
+
`result.task_id`, `result.submission` and `result.next` (the `get`/`wait`/
|
|
244
|
+
`stream` commands that pick the task up). A bookkeeping problem never reads
|
|
245
|
+
as "no task was created".
|
|
246
|
+
- `--async` returns after the POST (no polling). `get` is a query: any status
|
|
247
|
+
exits 0. `wait --timeout N` polls with a monotonic deadline (`0` = one query)
|
|
248
|
+
that also bounds every in-flight GET: a response arriving after the deadline
|
|
249
|
+
is a timeout (exit 8, last status kept, `result.task` null when none arrived
|
|
250
|
+
in time), never a late success, and no request starts once the budget is
|
|
251
|
+
spent. `stream` follows Server-Sent Events with `--timeout` (total) and
|
|
252
|
+
`--idle-timeout` (silence, keep-alives reset it); `-o` downloads the assets
|
|
253
|
+
in every output format, and in `ndjson` the final `outcome` line carries the
|
|
254
|
+
download manifest.
|
|
255
|
+
- `-o` on `get`/`wait`/`stream`/`make` downloads every artifact of a SUCCEEDED
|
|
256
|
+
task; `result.downloads.files` is a per-file manifest (key, path, bytes,
|
|
257
|
+
sha256, status). When the second asset fails, the state is `partial`, the files
|
|
258
|
+
already written stay listed and on disk, and the error keeps the asset host's
|
|
259
|
+
class and HTTP status (a 503 is `network`, exit 7, not a local I/O error). The
|
|
260
|
+
same holds for a failure *after* the transfers — relinking, digesting or
|
|
261
|
+
publishing the `meta.json` sidecar: `downloads.failed_step` names the step, the
|
|
262
|
+
manifest carries the digests actually on disk. The sidecar itself is published
|
|
263
|
+
like an asset (exclusive, no symlink, inside the root), so a file that appears
|
|
264
|
+
at its path during the download is never overwritten. The legacy schema
|
|
265
|
+
reports the same failures with additive `task_id`/`operation_id` fields and the
|
|
266
|
+
resume command as `hint`, so the accepted task is never lost from a default
|
|
267
|
+
`create -o` error.
|
|
268
|
+
- Ctrl-C stops waiting, streaming or downloading (exit 130) and sends no DELETE;
|
|
269
|
+
the envelope carries the task id, the command that resumes and the files that
|
|
270
|
+
had already landed. An interrupted transfer leaves no temp file behind.
|
|
271
|
+
|
|
152
272
|
## Resources
|
|
153
273
|
|
|
154
274
|
One command per endpoint. They are all registered and all supported, but they
|
|
155
275
|
are indexed by `meshy resources` rather than listed in `meshy --help` — that
|
|
156
276
|
help text is read on every invocation (an agent pays for the whole surface each
|
|
157
277
|
time), so it should not grow with the API. `meshy <resource> --help` documents
|
|
158
|
-
each one in full
|
|
278
|
+
each one in full; `meshy resources --output-schema v1` also lists the query and
|
|
279
|
+
local commands with their kind.
|
|
159
280
|
|
|
160
281
|
| Command | Meshy endpoint | Docs |
|
|
161
282
|
|---|---|---|
|
|
@@ -166,6 +287,7 @@ each one in full.
|
|
|
166
287
|
| `remesh` | `/remesh` | [docs](https://docs.meshy.ai/en/api/remesh) |
|
|
167
288
|
| `convert` | `/convert` | [docs](https://docs.meshy.ai/en/api/convert) |
|
|
168
289
|
| `resize` | `/resize` | [docs](https://docs.meshy.ai/en/api/resize) |
|
|
290
|
+
| `uv-unwrap` | `/uv-unwrap` | [docs](https://docs.meshy.ai/en/api/uv-unwrap) |
|
|
169
291
|
| `rigging` | `/rigging` | [docs](https://docs.meshy.ai/en/api/rigging) |
|
|
170
292
|
| `animate` | `/animations` | [docs](https://docs.meshy.ai/en/api/animations) |
|
|
171
293
|
| `text-to-motion` | `/text-to-motion` | [docs](https://docs.meshy.ai/en/api/text-to-motion) |
|
|
@@ -175,14 +297,18 @@ each one in full.
|
|
|
175
297
|
| `multi-color-print` | `/print/multi-color` | [docs](https://docs.meshy.ai/en/api/multi-color-print) |
|
|
176
298
|
| `analyze-printability` | `/print/analyze` | [docs](https://docs.meshy.ai/en/api/analyze-printability) |
|
|
177
299
|
| `repair-printability` | `/print/repair` | [docs](https://docs.meshy.ai/en/api/repair-printability) |
|
|
300
|
+
| `creative-lab <product> prototype\|build` | `/openapi/creative-lab/<product>/v1/<stage>` | [figure](https://docs.meshy.ai/en/api/creative-lab-figure) · [lamp](https://docs.meshy.ai/en/api/creative-lab-lamp) · [keychain](https://docs.meshy.ai/en/api/creative-lab-keychain) · [fridge-magnet](https://docs.meshy.ai/en/api/creative-lab-fridge-magnet) |
|
|
301
|
+
| `animation-catalog list` | `GET /web/public/animations/resources` (no key) | [docs](https://docs.meshy.ai/en/api/animations) |
|
|
302
|
+
| `showcases list` | `GET /showcases` (Enterprise; every request is billed) | [docs](https://docs.meshy.ai/en/api/enterprise-api) |
|
|
178
303
|
|
|
179
|
-
Per-resource actions (all single-HTTP-call):
|
|
304
|
+
Per-resource actions (all single-HTTP-call except `wait`/`stream`):
|
|
180
305
|
|
|
181
306
|
```
|
|
182
|
-
meshy-cli <resource> create [flags] [--data <json>] [--async] [--timeout <s>]
|
|
183
|
-
meshy-cli <resource> get <task-id>
|
|
307
|
+
meshy-cli <resource> create [flags] [--data <json>] [--async] [--timeout <s>] [--operation-id <id>]
|
|
308
|
+
meshy-cli <resource> get <task-id> [--save-json <file>] [--include-raw] [--project <dir>]
|
|
184
309
|
meshy-cli <resource> list [--page <n>] [--page-size <n>] [--sort-by <field>]
|
|
185
310
|
meshy-cli <resource> wait <task-id> [--timeout <s>]
|
|
311
|
+
meshy-cli <resource> stream <task-id> [--timeout <s>] [--idle-timeout <s>]
|
|
186
312
|
meshy-cli <resource> delete <task-id>
|
|
187
313
|
```
|
|
188
314
|
|
|
@@ -191,61 +317,158 @@ Top-level shortcut:
|
|
|
191
317
|
```
|
|
192
318
|
meshy-cli delete <task-id>
|
|
193
319
|
# Meshy's DELETE is unified across resources, but GET is not, so
|
|
194
|
-
# `get`/`wait` live only on their resource.
|
|
320
|
+
# `get`/`wait`/`stream` live only on their resource.
|
|
195
321
|
```
|
|
196
322
|
|
|
197
323
|
`create` is **synchronous by default** — it polls until the task reaches a
|
|
198
324
|
terminal status (`SUCCEEDED` / `FAILED` / `CANCELED`) or `--timeout` hits.
|
|
199
325
|
Pass `--async` to return the `task_id` immediately; then call
|
|
200
|
-
`<resource> get <id>` or
|
|
326
|
+
`<resource> get <id>`, `wait <id>` or `stream <id>` when you need the result.
|
|
327
|
+
|
|
328
|
+
### Creative Lab
|
|
329
|
+
|
|
330
|
+
Four products (`figure`, `lamp`, `keychain`, `fridge-magnet`), each with a
|
|
331
|
+
`prototype` stage (photo → styled concept image; the lamp prototype also yields
|
|
332
|
+
a lampshade GLB) and a `build` stage that consumes a SUCCEEDED prototype created
|
|
333
|
+
through this API with the same key. Build options are validated per product
|
|
334
|
+
before anything is sent: lamp `--options` (diameter, thickness, light-source
|
|
335
|
+
preset, rotations …) with `--model-format stl|zip`; keychain and fridge-magnet
|
|
336
|
+
relief options with `--model-format glb|obj|zip` — their `obj` output is a ZIP
|
|
337
|
+
bundle and is saved as `.zip`; figure has no options. Prototypes made in the
|
|
338
|
+
web app are rejected by the server (404).
|
|
201
339
|
|
|
202
|
-
## Saving artifacts with `-o`
|
|
340
|
+
## Saving artifacts with `-o` (legacy) and `meshy download` (selective)
|
|
203
341
|
|
|
204
342
|
When `-o` is set on a `create`/`wait`/`get`, the CLI downloads every artifact
|
|
205
|
-
the task produced, writes a sidecar metadata file, and prints a
|
|
206
|
-
instead of JSON. Single-file outputs get a per-file
|
|
207
|
-
|
|
208
|
-
|
|
343
|
+
the task produced, writes a sidecar metadata file, and (legacy schema) prints a
|
|
344
|
+
status report instead of JSON. Single-file outputs get a per-file
|
|
345
|
+
`<stem>_meta.json`; directory-mode outputs share a single `meta.json`. Under
|
|
346
|
+
`--output-schema v1` the same download is reported in `result.downloads`, and a
|
|
347
|
+
task that is not yet SUCCEEDED yields `downloads.state: "not_ready"` with exit 0.
|
|
209
348
|
|
|
210
349
|
```bash
|
|
211
|
-
|
|
212
|
-
# against the response Content-Type; sharp transcodes between
|
|
213
|
-
# jpg/png/webp/gif/tiff/avif so the file truly has the requested format.
|
|
214
|
-
meshy-cli text-to-image create --ai-model nano-banana --prompt "a leaf" \
|
|
215
|
-
-o assets/leaf.jpeg
|
|
216
|
-
|
|
217
|
-
# Multi-artifact task (3D, multi-view 2D, animation) — pass a directory.
|
|
218
|
-
# Files land with role-based names: model.glb, thumbnail.png,
|
|
219
|
-
# texture_0_base_color.png, animation_glb.glb, …
|
|
350
|
+
meshy-cli text-to-image create --ai-model nano-banana --prompt "a leaf" -o assets/leaf.jpeg
|
|
220
351
|
meshy-cli image-to-3d wait <id> -o out/robot/
|
|
221
352
|
```
|
|
222
353
|
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
354
|
+
`meshy download` is the selective, scriptable counterpart:
|
|
355
|
+
|
|
356
|
+
```bash
|
|
357
|
+
meshy download --task-json ./task.json --list # what is there?
|
|
358
|
+
meshy download --task-json ./task.json --model-format glb --output ./model.glb
|
|
359
|
+
meshy download --task-json ./rig.json --asset result.basic_animations.walking_glb_url --output ./walking.glb
|
|
360
|
+
meshy download --task-json ./task.json --kind thumbnail --output-dir ./previews/
|
|
361
|
+
meshy download --resource image-to-3d --task-id <id> --all --output-dir ./out/ # one GET, then the assets
|
|
362
|
+
meshy download --url https://assets.meshy.ai/... --output ./file.glb
|
|
363
|
+
```
|
|
364
|
+
|
|
365
|
+
Sources are `--task-json` (an API task, a legacy `meta.json`, or a v1 envelope),
|
|
366
|
+
`--url`, or `--resource` + `--task-id`; selectors are `--asset <key>` (repeatable),
|
|
367
|
+
`--model-format`, `--kind`, `--all`. With several assets and no selector the
|
|
368
|
+
command lists the candidates and exits 2 instead of guessing. Selecting an OBJ
|
|
369
|
+
pulls its MTL and textures (`--geometry-only` to skip); once the set has landed
|
|
370
|
+
the OBJ's `mtllib` and the MTL's `map_*` references are rewritten to the names
|
|
371
|
+
actually saved (`model.mtl`, `texture_0_base_color.png`, …) so the model loads
|
|
372
|
+
from that directory. Textures are matched by the name the server served them
|
|
373
|
+
under (then by channel), one candidate only: with several material groups a
|
|
374
|
+
reference that could mean two files is left as written and reported as
|
|
375
|
+
ambiguous, and a reference that merely equals one of the CLI's generated names
|
|
376
|
+
(`texture_0_base_color.png`) while the server called that image something else
|
|
377
|
+
is ambiguous too — identity follows the source, never the file name on disk.
|
|
378
|
+
Channel fallbacks (a channel word in the reference, the MTL key's channel, the
|
|
379
|
+
only texture there is) are heuristics and compete on the texture they actually
|
|
380
|
+
reach: when two different references would both fall back to the same image, or
|
|
381
|
+
one reference would go to different images under different keys, they all stay
|
|
382
|
+
as written and are reported as ambiguous — the CLI never merges material groups
|
|
383
|
+
without evidence that they name the same file. Every link is listed under `result.downloads.material_links`
|
|
384
|
+
(`status: complete | incomplete`, the `newmtl` group of each map), rewritten
|
|
385
|
+
files carry `relinked: true` with their final sha256, and a reference that
|
|
386
|
+
matches no or several downloaded files stays as written and is warned
|
|
387
|
+
(`material_reference_unresolved` / `material_reference_ambiguous`). Files are published
|
|
388
|
+
exclusively (never overwritten without `--overwrite`), checked against the
|
|
389
|
+
content type and magic bytes, kept inside the output directory (or `--workspace`),
|
|
390
|
+
and listed with size and sha256 in `result.downloads.files`. With `--project <dir>`
|
|
391
|
+
the files that landed inside the project are recorded in its `metadata.json`;
|
|
392
|
+
when that record fails after the transfer (metadata.json replaced by a symlink,
|
|
393
|
+
damaged, or locked) the command exits 11 with the complete `result` — manifest,
|
|
394
|
+
`saved_json`, `project.action: "failed"` — and `error.recovery.command` is the
|
|
395
|
+
one `meshy project record …` invocation that redoes the record — carrying the
|
|
396
|
+
original `--workspace`, so a recovery never writes further than the command that
|
|
397
|
+
failed; the assets stay where they landed. Problems visible before the transfer (no metadata.json, a
|
|
398
|
+
symlink or invalid JSON in its place, a blank `--stage`) are refused with no
|
|
399
|
+
request made. Asset hosts never
|
|
400
|
+
receive the API credential; an expired signed URL is refreshed once when the
|
|
401
|
+
task came from the API and reported as unrefreshable when it came from a file.
|
|
402
|
+
|
|
403
|
+
## Projects (`meshy_output/`)
|
|
404
|
+
|
|
405
|
+
The Skills' project layout, without Python:
|
|
406
|
+
|
|
407
|
+
```bash
|
|
408
|
+
meshy project init --root ./meshy_output --name "demo" --task-id <id>
|
|
409
|
+
meshy text-to-3d wait <id> --project ./meshy_output/<folder> # saves task_<id>.json, records the stage
|
|
410
|
+
meshy project record --project ./meshy_output/<folder> --task-id <id> --resource text-to-3d --stage preview --file preview.glb
|
|
411
|
+
meshy project show --project ./meshy_output/<folder>
|
|
412
|
+
meshy project list --root ./meshy_output
|
|
413
|
+
meshy project rebuild-index --root ./meshy_output
|
|
414
|
+
```
|
|
415
|
+
|
|
416
|
+
`metadata.json` (schema 2; legacy files are read as-is and migrated on the first
|
|
417
|
+
write with a backup) is the source of truth; `history.json` is a rebuildable
|
|
418
|
+
index. A repeat `(task_id, stage)` merges instead of duplicating.
|
|
419
|
+
|
|
420
|
+
## Printing helpers
|
|
421
|
+
|
|
422
|
+
```bash
|
|
423
|
+
meshy inspect faces --task-json ./task.json --max-faces 300000 # pass (0) | fail (12) | unknown (13)
|
|
424
|
+
meshy mesh prepare-print ./model.obj --height-mm 75 # writes ./model.print.obj
|
|
425
|
+
meshy mesh prepare-print ./model.obj --height-mm 80 --in-place
|
|
426
|
+
meshy slicer detect
|
|
427
|
+
meshy slicer open --slicer OrcaSlicer --file ./model.print.obj
|
|
428
|
+
```
|
|
429
|
+
|
|
430
|
+
`inspect faces` answers only whether the task's `face_count` is within the
|
|
431
|
+
limit you pass (`--max-faces` is required); a missing count is `unknown`, never
|
|
432
|
+
0, and a failing verdict only *describes* a remesh. `prepare-print` rotates a
|
|
433
|
+
Y-up OBJ to Z-up, scales it to the target height, centres it on XY and rests it
|
|
434
|
+
on Z=0, preserving faces, UVs, normals (rotated only) and material references;
|
|
435
|
+
it never overwrites without `--in-place`, and the MTL/texture copies it makes
|
|
436
|
+
beside the output are proven — on real paths, before any directory is created —
|
|
437
|
+
to lie inside the output directory (or `--workspace`), so a symlinked
|
|
438
|
+
`materials/` cannot redirect them. `slicer open` launches only a
|
|
439
|
+
registered slicer at its detected path with the file as a single argument — no
|
|
440
|
+
shell, no default-application fallback; `launch_requested` is not proof that
|
|
441
|
+
the import succeeded.
|
|
226
442
|
|
|
227
443
|
## Image and 3D-model inputs
|
|
228
444
|
|
|
229
445
|
Flags that take a media source (`--image-url`, `--image-urls`,
|
|
230
446
|
`--reference-image-urls`, `--texture-image-url`, `--image-style-url`,
|
|
231
|
-
`--multiview-image-urls`, `--model-url`)
|
|
447
|
+
`--multiview-image-urls`, `--model-url`) — and the same fields inside `--data` —
|
|
448
|
+
accept:
|
|
232
449
|
|
|
233
|
-
- **http(s) URLs** — preflighted with HEAD so unreachable sources fail fast.
|
|
450
|
+
- **http(s) URLs** — preflighted with an unauthenticated HEAD so unreachable sources fail fast.
|
|
234
451
|
- **Local file paths** — absolute or relative to cwd. MIME-sniffed via magic
|
|
235
|
-
bytes (with extension fallback) and inlined as `data:` URIs on the wire.
|
|
452
|
+
bytes (with extension fallback), size-capped, and inlined as `data:` URIs on the wire.
|
|
453
|
+
- **`data:` URIs** — validated (base64, MIME kind, size) and passed through.
|
|
236
454
|
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
455
|
+
Missing files and 4xx/5xx preflights exit with code `2` and a flag-prefixed
|
|
456
|
+
message before any task is created. GLB-only fields (`uv-unwrap`, `rigging`
|
|
457
|
+
`--model-url`) reject other formats locally.
|
|
240
458
|
|
|
241
459
|
## Global flags
|
|
242
460
|
|
|
243
461
|
| Flag | Purpose |
|
|
244
462
|
|------|---------|
|
|
245
463
|
| `--api-key <key>` | Override `MESHY_API_KEY` |
|
|
464
|
+
| `--api-key-file <path>` | Read `MESHY_API_KEY` from an explicit dotenv-style file (only that key) |
|
|
246
465
|
| `--base-url-v1 <url>` / `--base-url-v2 <url>` | Override endpoints (staging/proxy) |
|
|
247
|
-
| `--
|
|
248
|
-
|
|
|
466
|
+
| `--base-url-creative-lab <url>` | Override the Creative Lab base (default: `<v1 origin>/openapi/creative-lab`) |
|
|
467
|
+
| `--output-schema legacy\|v1` | Stdout data model (existing commands default to `legacy`; new commands are `v1`) |
|
|
468
|
+
| `--format json\|pretty\|ndjson` | Stdout rendering (default `json`) |
|
|
469
|
+
| `-o, --output <path>` | Download artifacts to a file/directory (task commands); output file for `mesh prepare-print` |
|
|
470
|
+
| `--workspace <dir>` | Confine every written file to this directory: `download`, `-o` on task verbs and `make` (report-only tasks included), `--save-json`, `--project`/project folders and the history index (skipped with `index_dirty` when its root would fall outside), `mesh prepare-print` outputs and their copied materials — checked on real paths before anything, even a directory, is created. The boundary is frozen when the command starts (real path and directory identity): a workspace or project replaced by a symlink while a request is in flight is refused, never followed |
|
|
471
|
+
| `--no-update-check` | Skip the background npm version check in this process |
|
|
249
472
|
| `-v, --verbose` | Debug logging to stderr |
|
|
250
473
|
| `--log-level <level>` | `debug \| info \| warn \| error \| silent` |
|
|
251
474
|
|
|
@@ -253,44 +476,50 @@ exit with code `2` and a flag-prefixed message before any task is created.
|
|
|
253
476
|
|
|
254
477
|
| Code | Meaning |
|
|
255
478
|
|------|---------|
|
|
256
|
-
| 0 | success |
|
|
257
|
-
| 1 |
|
|
258
|
-
| 2 | usage (flag parse error) |
|
|
259
|
-
| 3 | auth (`401
|
|
260
|
-
| 4 | validation (`400`, `422
|
|
261
|
-
| 5 | not found (`404
|
|
479
|
+
| 0 | success (including `get` of any task status, empty lists, local checks that pass) |
|
|
480
|
+
| 1 | task ended FAILED/CANCELED while waiting, or an unclassified error |
|
|
481
|
+
| 2 | usage (flag parse error, conflicting or missing arguments) |
|
|
482
|
+
| 3 | auth (`401`, no usable credential) |
|
|
483
|
+
| 4 | validation (`400`, `422`, locally rejected payload) |
|
|
484
|
+
| 5 | not found (`404`; the cause is not guessed) |
|
|
262
485
|
| 6 | rate limit (`429`) |
|
|
263
|
-
| 7 | network |
|
|
264
|
-
| 8 | timed out waiting for a task |
|
|
486
|
+
| 7 | network (read failures, stream disconnects) |
|
|
487
|
+
| 8 | timed out waiting for or streaming a task (the task keeps running) |
|
|
265
488
|
| 9 | credit exhausted (`402`) |
|
|
489
|
+
| 10 | submission unknown — a create was sent but its outcome could not be confirmed |
|
|
490
|
+
| 11 | local I/O — refused overwrite, path outside the authorised root, journal/project write failure |
|
|
491
|
+
| 12 | check failed (`inspect faces` over the limit) |
|
|
492
|
+
| 13 | check unknown (`inspect faces` without a usable face count) |
|
|
493
|
+
| 130 | interrupted (Ctrl-C); nothing was deleted server-side |
|
|
266
494
|
|
|
267
495
|
## Environment variables
|
|
268
496
|
|
|
269
497
|
| Variable | Default |
|
|
270
498
|
|---|---|
|
|
271
|
-
| `MESHY_API_KEY` | — (required unless a profile is stored) |
|
|
499
|
+
| `MESHY_API_KEY` | — (required unless a profile is stored or `--api-key-file` is given) |
|
|
272
500
|
| `MESHY_BASE_URL_V1` | `https://api.meshy.ai/openapi/v1` |
|
|
273
501
|
| `MESHY_BASE_URL_V2` | `https://api.meshy.ai/openapi/v2` |
|
|
502
|
+
| `MESHY_BASE_URL_CREATIVE_LAB` | derived from the v1 origin (`/openapi/creative-lab`) |
|
|
274
503
|
| `MESHY_OAUTH_AUTHORIZE_URL` | `https://www.meshy.ai/oauth/authorize` — override for staging/testing |
|
|
275
504
|
| `MESHY_CLI_NO_BROWSER` | unset — set to `1` to suppress browser open (URL still printed to stderr) |
|
|
276
|
-
| `
|
|
277
|
-
| `
|
|
505
|
+
| `MESHY_CONFIG_DIR` | `~/.config/meshy` (credentials, operation journal, update cache) |
|
|
506
|
+
| `MESHY_CONNECT_TIMEOUT_MS` | `10000` (read for compatibility; fetch has no separate connect timeout) |
|
|
507
|
+
| `MESHY_READ_TIMEOUT_MS` | `120000` — covers headers *and* body |
|
|
278
508
|
| `MESHY_POLL_INTERVAL_MS` | `3000` |
|
|
279
509
|
| `MESHY_LOG_LEVEL` | `warn` |
|
|
280
510
|
| `MESHY_CLI_NO_UPDATE_NOTIFIER` | unset — any non-empty value disables update checks; CI envs (`CI`, `GITHUB_ACTIONS`, `BUILD_NUMBER`, `RUN_ID`) auto-skip |
|
|
281
511
|
|
|
282
512
|
## Update notifications
|
|
283
513
|
|
|
284
|
-
meshy-cli checks the npm registry for a newer version at most once per 24 hours. The result is cached at
|
|
514
|
+
meshy-cli checks the npm registry for a newer version at most once per 24 hours. The result is cached at `<MESHY_CONFIG_DIR>/update-state.json`. The refresh runs in a detached background process so it can never slow down or fail a command, and it never runs for local commands (`resources`, `project`, `inspect`, `mesh`, `slicer`, `doctor`, `download`, `animation-catalog`), for `make --dry-run`, or with `--no-update-check`.
|
|
285
515
|
|
|
286
516
|
When a newer version is available:
|
|
287
517
|
|
|
288
|
-
- **JSON object outputs**
|
|
289
|
-
- **
|
|
290
|
-
- **
|
|
518
|
+
- **Legacy JSON object outputs** carry a top-level `_notice.update = { current, latest, message, command }` so agents can relay it to the user.
|
|
519
|
+
- **v1 envelopes are never decorated** — the six keys are the contract; humans get the hint on stderr.
|
|
520
|
+
- **ndjson arrays** (legacy) carry `_notice.update` on the **first line only**.
|
|
291
521
|
- **Humans on an interactive terminal** get a single line on stderr after the command output.
|
|
292
522
|
- **stdout is never polluted** — the notice never appears on stdout.
|
|
293
|
-
- **Skipped automatically** in CI environments and for development builds.
|
|
294
523
|
|
|
295
524
|
## Agent skills
|
|
296
525
|
|
|
@@ -298,43 +527,50 @@ The `skills/` directory contains markdown-based skills for AI coding agents
|
|
|
298
527
|
(Claude Code, etc.):
|
|
299
528
|
|
|
300
529
|
- [`skills/meshy-cli`](skills/meshy-cli/SKILL.md) — a single skill covering
|
|
301
|
-
setup, `make`, the shared verb contract, the API constraints
|
|
302
|
-
failed tasks when ignored, and the exit-code table.
|
|
530
|
+
setup, `make`, the shared verb contract, the v1 envelope, the API constraints
|
|
531
|
+
that produce failed tasks when ignored, the local helpers, and the exit-code table.
|
|
303
532
|
|
|
304
533
|
It is deliberately short. A skill is loaded into an agent's context on every
|
|
305
534
|
invocation, so length is a running cost; anything an agent can look up on
|
|
306
535
|
demand (`meshy resources`, `meshy <resource> --help`,
|
|
307
536
|
<https://docs.meshy.ai/en/api/>) is linked rather than copied.
|
|
308
537
|
|
|
538
|
+
## Skill-parity documentation
|
|
539
|
+
|
|
540
|
+
`docs/skill-parity/` records how this release covers the execution capabilities
|
|
541
|
+
of the Meshy Skills without Python: the frozen baseline, the endpoint contracts,
|
|
542
|
+
the capability matrix, design decisions, migration notes with every intentional
|
|
543
|
+
difference, and the verification record.
|
|
544
|
+
|
|
309
545
|
## Project layout
|
|
310
546
|
|
|
311
547
|
```
|
|
312
548
|
meshy-cli/
|
|
313
549
|
├── src/
|
|
314
|
-
│ ├── index.ts # CLI entry
|
|
550
|
+
│ ├── index.ts # CLI entry: update-check policy, SIGINT, unified error exit
|
|
315
551
|
│ ├── root.ts # root command + global flag wiring
|
|
316
|
-
│ ├── cmd/ # make
|
|
317
|
-
│
|
|
552
|
+
│ ├── cmd/ # make, auth, balance, resources, api, one file per endpoint,
|
|
553
|
+
│ │ # uv-unwrap, creative-lab, animation-catalog, showcases,
|
|
554
|
+
│ │ # download, project, inspect, mesh, slicer, doctor
|
|
555
|
+
│ ├── client/
|
|
556
|
+
│ │ ├── resource-registry.ts # every resource: path, family, verbs, billing, media fields
|
|
557
|
+
│ │ ├── transport.ts # per-family HTTP transport (auth scope, deadlines, redirects)
|
|
558
|
+
│ │ ├── endpoints/ # TaskEndpoint + balance / catalog / showcases
|
|
559
|
+
│ │ └── types.ts # Zod task schemas
|
|
318
560
|
│ └── internal/
|
|
319
|
-
│ ├──
|
|
320
|
-
│ ├──
|
|
321
|
-
│ ├──
|
|
322
|
-
│ ├──
|
|
323
|
-
│ ├──
|
|
324
|
-
│ ├──
|
|
325
|
-
│ ├──
|
|
326
|
-
│ ├──
|
|
327
|
-
│
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
│ ├── errors.ts # UsageError + exit-code mapping
|
|
332
|
-
│ ├── global-options.ts # mirror --format etc. onto subcommands
|
|
333
|
-
│ └── logger.ts # leveled stderr logger
|
|
334
|
-
├── tests/ # node:test unit + integration tests
|
|
335
|
-
├── skills/ # agent-facing skill: SKILL.md + bundled animation catalog (published)
|
|
561
|
+
│ ├── result.ts / errors.ts # v1 envelope, error codes, exit codes
|
|
562
|
+
│ ├── task-command.ts # create/get/list/wait/stream/delete factory
|
|
563
|
+
│ ├── operation-store.ts # submission journal (single POST, unknown outcomes)
|
|
564
|
+
│ ├── stream.ts / poll.ts # SSE parser + cancellable polling
|
|
565
|
+
│ ├── artifacts.ts / download.ts # asset keys, safe downloads, legacy -o
|
|
566
|
+
│ ├── project-store.ts # meshy_output metadata + history
|
|
567
|
+
│ ├── inspect.ts / obj-transform.ts / slicers.ts / doctor.ts
|
|
568
|
+
│ ├── config.ts / runtime.ts / env-file.ts / credentials.ts / oauth.ts
|
|
569
|
+
│ └── atomic-file.ts / paths.ts / lock.ts
|
|
570
|
+
├── tests/ # node:test unit, contract and black-box tests
|
|
571
|
+
├── skills/ # agent-facing skill (published)
|
|
572
|
+
├── docs/skill-parity/ # baseline, contracts, matrix, decisions, verification
|
|
336
573
|
├── package.json
|
|
337
|
-
├── tsconfig.json
|
|
338
574
|
└── README.md
|
|
339
575
|
```
|
|
340
576
|
|
|
@@ -342,24 +578,22 @@ meshy-cli/
|
|
|
342
578
|
|
|
343
579
|
- **Two layers, one of them opinion-free.** `make` chains endpoints; the
|
|
344
580
|
resource commands expose them one at a time. `make` picks its chain from the
|
|
345
|
-
input type alone and stops there.
|
|
346
|
-
image first, confirming a shape before texturing, a polycount that rigs well
|
|
347
|
-
— is a judgement about someone else's asset and someone else's credits, so it
|
|
348
|
-
stays with the caller rather than being baked into a default.
|
|
581
|
+
input type alone and stops there.
|
|
349
582
|
- **Plan first, then spend.** `make` computes the whole chain before creating
|
|
350
583
|
anything, so `--dry-run` and a real run share one code path and one estimate.
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
- **
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
584
|
+
- **One POST, journaled.** Every billable create is recorded before it is sent;
|
|
585
|
+
a lost answer is reported as unknown, never re-sent.
|
|
586
|
+
- **One registry.** `src/client/resource-registry.ts` is the only place a path,
|
|
587
|
+
API family, verb set or media field is declared; commands, the `resources`
|
|
588
|
+
index and the transport all read from it.
|
|
589
|
+
- **Credentials have a scope.** The API credential goes to the API origins it
|
|
590
|
+
was resolved for and nowhere else — not to asset hosts, not to the public
|
|
591
|
+
catalog, not across redirects.
|
|
358
592
|
- **`--data` escape hatch.** Every `create` accepts a raw JSON object (or
|
|
359
|
-
`@file.json`) that merges with structured flags
|
|
360
|
-
|
|
361
|
-
- **Stdout is reserved for command output.** Logs and errors go
|
|
362
|
-
pipes (`| jq`, `-o file`) stay clean.
|
|
593
|
+
`@file.json`) that merges with structured flags (flags win, explicit `false`
|
|
594
|
+
and `0` survive).
|
|
595
|
+
- **Stdout is reserved for command output.** Logs, progress and errors' prose go
|
|
596
|
+
to stderr so pipes (`| jq`, `-o file`) stay clean.
|
|
363
597
|
|
|
364
598
|
## License
|
|
365
599
|
|