@meshy-ai/cli 0.1.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.
Files changed (265) hide show
  1. package/.env.example +14 -0
  2. package/LICENSE +21 -0
  3. package/README.md +376 -0
  4. package/dist/client/endpoints/analyze-printability.d.ts +5 -0
  5. package/dist/client/endpoints/analyze-printability.d.ts.map +1 -0
  6. package/dist/client/endpoints/analyze-printability.js +7 -0
  7. package/dist/client/endpoints/analyze-printability.js.map +1 -0
  8. package/dist/client/endpoints/animate.d.ts +6 -0
  9. package/dist/client/endpoints/animate.d.ts.map +1 -0
  10. package/dist/client/endpoints/animate.js +8 -0
  11. package/dist/client/endpoints/animate.js.map +1 -0
  12. package/dist/client/endpoints/balance.d.ts +9 -0
  13. package/dist/client/endpoints/balance.d.ts.map +1 -0
  14. package/dist/client/endpoints/balance.js +27 -0
  15. package/dist/client/endpoints/balance.js.map +1 -0
  16. package/dist/client/endpoints/base.d.ts +24 -0
  17. package/dist/client/endpoints/base.d.ts.map +1 -0
  18. package/dist/client/endpoints/base.js +87 -0
  19. package/dist/client/endpoints/base.js.map +1 -0
  20. package/dist/client/endpoints/convert.d.ts +5 -0
  21. package/dist/client/endpoints/convert.d.ts.map +1 -0
  22. package/dist/client/endpoints/convert.js +7 -0
  23. package/dist/client/endpoints/convert.js.map +1 -0
  24. package/dist/client/endpoints/image-to-3d.d.ts +5 -0
  25. package/dist/client/endpoints/image-to-3d.d.ts.map +1 -0
  26. package/dist/client/endpoints/image-to-3d.js +7 -0
  27. package/dist/client/endpoints/image-to-3d.js.map +1 -0
  28. package/dist/client/endpoints/image-to-image.d.ts +5 -0
  29. package/dist/client/endpoints/image-to-image.d.ts.map +1 -0
  30. package/dist/client/endpoints/image-to-image.js +7 -0
  31. package/dist/client/endpoints/image-to-image.js.map +1 -0
  32. package/dist/client/endpoints/multi-color-print.d.ts +5 -0
  33. package/dist/client/endpoints/multi-color-print.d.ts.map +1 -0
  34. package/dist/client/endpoints/multi-color-print.js +7 -0
  35. package/dist/client/endpoints/multi-color-print.js.map +1 -0
  36. package/dist/client/endpoints/multi-image-to-3d.d.ts +5 -0
  37. package/dist/client/endpoints/multi-image-to-3d.d.ts.map +1 -0
  38. package/dist/client/endpoints/multi-image-to-3d.js +7 -0
  39. package/dist/client/endpoints/multi-image-to-3d.js.map +1 -0
  40. package/dist/client/endpoints/remesh.d.ts +5 -0
  41. package/dist/client/endpoints/remesh.d.ts.map +1 -0
  42. package/dist/client/endpoints/remesh.js +7 -0
  43. package/dist/client/endpoints/remesh.js.map +1 -0
  44. package/dist/client/endpoints/repair-printability.d.ts +5 -0
  45. package/dist/client/endpoints/repair-printability.d.ts.map +1 -0
  46. package/dist/client/endpoints/repair-printability.js +7 -0
  47. package/dist/client/endpoints/repair-printability.js.map +1 -0
  48. package/dist/client/endpoints/resize.d.ts +5 -0
  49. package/dist/client/endpoints/resize.d.ts.map +1 -0
  50. package/dist/client/endpoints/resize.js +7 -0
  51. package/dist/client/endpoints/resize.js.map +1 -0
  52. package/dist/client/endpoints/retexture.d.ts +5 -0
  53. package/dist/client/endpoints/retexture.d.ts.map +1 -0
  54. package/dist/client/endpoints/retexture.js +7 -0
  55. package/dist/client/endpoints/retexture.js.map +1 -0
  56. package/dist/client/endpoints/rigging.d.ts +6 -0
  57. package/dist/client/endpoints/rigging.d.ts.map +1 -0
  58. package/dist/client/endpoints/rigging.js +8 -0
  59. package/dist/client/endpoints/rigging.js.map +1 -0
  60. package/dist/client/endpoints/text-to-3d.d.ts +6 -0
  61. package/dist/client/endpoints/text-to-3d.d.ts.map +1 -0
  62. package/dist/client/endpoints/text-to-3d.js +8 -0
  63. package/dist/client/endpoints/text-to-3d.js.map +1 -0
  64. package/dist/client/endpoints/text-to-image.d.ts +5 -0
  65. package/dist/client/endpoints/text-to-image.d.ts.map +1 -0
  66. package/dist/client/endpoints/text-to-image.js +7 -0
  67. package/dist/client/endpoints/text-to-image.js.map +1 -0
  68. package/dist/client/errors.d.ts +23 -0
  69. package/dist/client/errors.d.ts.map +1 -0
  70. package/dist/client/errors.js +82 -0
  71. package/dist/client/errors.js.map +1 -0
  72. package/dist/client/index.d.ts +48 -0
  73. package/dist/client/index.d.ts.map +1 -0
  74. package/dist/client/index.js +147 -0
  75. package/dist/client/index.js.map +1 -0
  76. package/dist/client/types.d.ts +298 -0
  77. package/dist/client/types.d.ts.map +1 -0
  78. package/dist/client/types.js +97 -0
  79. package/dist/client/types.js.map +1 -0
  80. package/dist/cmd/analyze-printability.d.ts +8 -0
  81. package/dist/cmd/analyze-printability.d.ts.map +1 -0
  82. package/dist/cmd/analyze-printability.js +34 -0
  83. package/dist/cmd/analyze-printability.js.map +1 -0
  84. package/dist/cmd/animate.d.ts +9 -0
  85. package/dist/cmd/animate.d.ts.map +1 -0
  86. package/dist/cmd/animate.js +51 -0
  87. package/dist/cmd/animate.js.map +1 -0
  88. package/dist/cmd/api.d.ts +9 -0
  89. package/dist/cmd/api.d.ts.map +1 -0
  90. package/dist/cmd/api.js +50 -0
  91. package/dist/cmd/api.js.map +1 -0
  92. package/dist/cmd/auth.d.ts +19 -0
  93. package/dist/cmd/auth.d.ts.map +1 -0
  94. package/dist/cmd/auth.js +583 -0
  95. package/dist/cmd/auth.js.map +1 -0
  96. package/dist/cmd/balance.d.ts +6 -0
  97. package/dist/cmd/balance.d.ts.map +1 -0
  98. package/dist/cmd/balance.js +14 -0
  99. package/dist/cmd/balance.js.map +1 -0
  100. package/dist/cmd/convert.d.ts +8 -0
  101. package/dist/cmd/convert.d.ts.map +1 -0
  102. package/dist/cmd/convert.js +40 -0
  103. package/dist/cmd/convert.js.map +1 -0
  104. package/dist/cmd/delete.d.ts +7 -0
  105. package/dist/cmd/delete.d.ts.map +1 -0
  106. package/dist/cmd/delete.js +19 -0
  107. package/dist/cmd/delete.js.map +1 -0
  108. package/dist/cmd/image-to-3d.d.ts +12 -0
  109. package/dist/cmd/image-to-3d.d.ts.map +1 -0
  110. package/dist/cmd/image-to-3d.js +97 -0
  111. package/dist/cmd/image-to-3d.js.map +1 -0
  112. package/dist/cmd/image-to-image.d.ts +5 -0
  113. package/dist/cmd/image-to-image.d.ts.map +1 -0
  114. package/dist/cmd/image-to-image.js +56 -0
  115. package/dist/cmd/image-to-image.js.map +1 -0
  116. package/dist/cmd/make.d.ts +31 -0
  117. package/dist/cmd/make.d.ts.map +1 -0
  118. package/dist/cmd/make.js +195 -0
  119. package/dist/cmd/make.js.map +1 -0
  120. package/dist/cmd/multi-color-print.d.ts +6 -0
  121. package/dist/cmd/multi-color-print.d.ts.map +1 -0
  122. package/dist/cmd/multi-color-print.js +44 -0
  123. package/dist/cmd/multi-color-print.js.map +1 -0
  124. package/dist/cmd/multi-image-to-3d.d.ts +5 -0
  125. package/dist/cmd/multi-image-to-3d.d.ts.map +1 -0
  126. package/dist/cmd/multi-image-to-3d.js +72 -0
  127. package/dist/cmd/multi-image-to-3d.js.map +1 -0
  128. package/dist/cmd/remesh.d.ts +8 -0
  129. package/dist/cmd/remesh.d.ts.map +1 -0
  130. package/dist/cmd/remesh.js +49 -0
  131. package/dist/cmd/remesh.js.map +1 -0
  132. package/dist/cmd/repair-printability.d.ts +7 -0
  133. package/dist/cmd/repair-printability.d.ts.map +1 -0
  134. package/dist/cmd/repair-printability.js +32 -0
  135. package/dist/cmd/repair-printability.js.map +1 -0
  136. package/dist/cmd/resize.d.ts +8 -0
  137. package/dist/cmd/resize.d.ts.map +1 -0
  138. package/dist/cmd/resize.js +51 -0
  139. package/dist/cmd/resize.js.map +1 -0
  140. package/dist/cmd/resources.d.ts +18 -0
  141. package/dist/cmd/resources.d.ts.map +1 -0
  142. package/dist/cmd/resources.js +59 -0
  143. package/dist/cmd/resources.js.map +1 -0
  144. package/dist/cmd/retexture.d.ts +5 -0
  145. package/dist/cmd/retexture.d.ts.map +1 -0
  146. package/dist/cmd/retexture.js +64 -0
  147. package/dist/cmd/retexture.js.map +1 -0
  148. package/dist/cmd/rigging.d.ts +6 -0
  149. package/dist/cmd/rigging.d.ts.map +1 -0
  150. package/dist/cmd/rigging.js +40 -0
  151. package/dist/cmd/rigging.js.map +1 -0
  152. package/dist/cmd/text-to-3d.d.ts +14 -0
  153. package/dist/cmd/text-to-3d.d.ts.map +1 -0
  154. package/dist/cmd/text-to-3d.js +76 -0
  155. package/dist/cmd/text-to-3d.js.map +1 -0
  156. package/dist/cmd/text-to-image.d.ts +5 -0
  157. package/dist/cmd/text-to-image.d.ts.map +1 -0
  158. package/dist/cmd/text-to-image.js +53 -0
  159. package/dist/cmd/text-to-image.js.map +1 -0
  160. package/dist/index.d.ts +6 -0
  161. package/dist/index.d.ts.map +1 -0
  162. package/dist/index.js +46 -0
  163. package/dist/index.js.map +1 -0
  164. package/dist/internal/config.d.ts +46 -0
  165. package/dist/internal/config.d.ts.map +1 -0
  166. package/dist/internal/config.js +94 -0
  167. package/dist/internal/config.js.map +1 -0
  168. package/dist/internal/credentials.d.ts +106 -0
  169. package/dist/internal/credentials.d.ts.map +1 -0
  170. package/dist/internal/credentials.js +297 -0
  171. package/dist/internal/credentials.js.map +1 -0
  172. package/dist/internal/device-state.d.ts +45 -0
  173. package/dist/internal/device-state.d.ts.map +1 -0
  174. package/dist/internal/device-state.js +180 -0
  175. package/dist/internal/device-state.js.map +1 -0
  176. package/dist/internal/device.d.ts +79 -0
  177. package/dist/internal/device.d.ts.map +1 -0
  178. package/dist/internal/device.js +374 -0
  179. package/dist/internal/device.js.map +1 -0
  180. package/dist/internal/download.d.ts +34 -0
  181. package/dist/internal/download.d.ts.map +1 -0
  182. package/dist/internal/download.js +283 -0
  183. package/dist/internal/download.js.map +1 -0
  184. package/dist/internal/errors.d.ts +66 -0
  185. package/dist/internal/errors.d.ts.map +1 -0
  186. package/dist/internal/errors.js +169 -0
  187. package/dist/internal/errors.js.map +1 -0
  188. package/dist/internal/file-input.d.ts +24 -0
  189. package/dist/internal/file-input.d.ts.map +1 -0
  190. package/dist/internal/file-input.js +164 -0
  191. package/dist/internal/file-input.js.map +1 -0
  192. package/dist/internal/flags.d.ts +9 -0
  193. package/dist/internal/flags.d.ts.map +1 -0
  194. package/dist/internal/flags.js +31 -0
  195. package/dist/internal/flags.js.map +1 -0
  196. package/dist/internal/global-options.d.ts +16 -0
  197. package/dist/internal/global-options.d.ts.map +1 -0
  198. package/dist/internal/global-options.js +57 -0
  199. package/dist/internal/global-options.js.map +1 -0
  200. package/dist/internal/headless.d.ts +69 -0
  201. package/dist/internal/headless.d.ts.map +1 -0
  202. package/dist/internal/headless.js +101 -0
  203. package/dist/internal/headless.js.map +1 -0
  204. package/dist/internal/image-models.d.ts +20 -0
  205. package/dist/internal/image-models.d.ts.map +1 -0
  206. package/dist/internal/image-models.js +40 -0
  207. package/dist/internal/image-models.js.map +1 -0
  208. package/dist/internal/logger.d.ts +14 -0
  209. package/dist/internal/logger.d.ts.map +1 -0
  210. package/dist/internal/logger.js +42 -0
  211. package/dist/internal/logger.js.map +1 -0
  212. package/dist/internal/make-plan.d.ts +41 -0
  213. package/dist/internal/make-plan.d.ts.map +1 -0
  214. package/dist/internal/make-plan.js +67 -0
  215. package/dist/internal/make-plan.js.map +1 -0
  216. package/dist/internal/oauth.d.ts +95 -0
  217. package/dist/internal/oauth.d.ts.map +1 -0
  218. package/dist/internal/oauth.js +365 -0
  219. package/dist/internal/oauth.js.map +1 -0
  220. package/dist/internal/output.d.ts +15 -0
  221. package/dist/internal/output.d.ts.map +1 -0
  222. package/dist/internal/output.js +66 -0
  223. package/dist/internal/output.js.map +1 -0
  224. package/dist/internal/payload.d.ts +9 -0
  225. package/dist/internal/payload.d.ts.map +1 -0
  226. package/dist/internal/payload.js +42 -0
  227. package/dist/internal/payload.js.map +1 -0
  228. package/dist/internal/poll.d.ts +17 -0
  229. package/dist/internal/poll.d.ts.map +1 -0
  230. package/dist/internal/poll.js +27 -0
  231. package/dist/internal/poll.js.map +1 -0
  232. package/dist/internal/pricing.d.ts +23 -0
  233. package/dist/internal/pricing.d.ts.map +1 -0
  234. package/dist/internal/pricing.js +24 -0
  235. package/dist/internal/pricing.js.map +1 -0
  236. package/dist/internal/report.d.ts +40 -0
  237. package/dist/internal/report.d.ts.map +1 -0
  238. package/dist/internal/report.js +48 -0
  239. package/dist/internal/report.js.map +1 -0
  240. package/dist/internal/runtime.d.ts +66 -0
  241. package/dist/internal/runtime.d.ts.map +1 -0
  242. package/dist/internal/runtime.js +160 -0
  243. package/dist/internal/runtime.js.map +1 -0
  244. package/dist/internal/task-command.d.ts +39 -0
  245. package/dist/internal/task-command.d.ts.map +1 -0
  246. package/dist/internal/task-command.js +189 -0
  247. package/dist/internal/task-command.js.map +1 -0
  248. package/dist/internal/update-notifier.d.ts +160 -0
  249. package/dist/internal/update-notifier.d.ts.map +1 -0
  250. package/dist/internal/update-notifier.js +445 -0
  251. package/dist/internal/update-notifier.js.map +1 -0
  252. package/dist/internal/user-agent.d.ts +6 -0
  253. package/dist/internal/user-agent.d.ts.map +1 -0
  254. package/dist/internal/user-agent.js +7 -0
  255. package/dist/internal/user-agent.js.map +1 -0
  256. package/dist/internal/version.d.ts +2 -0
  257. package/dist/internal/version.d.ts.map +1 -0
  258. package/dist/internal/version.js +11 -0
  259. package/dist/internal/version.js.map +1 -0
  260. package/dist/root.d.ts +13 -0
  261. package/dist/root.d.ts.map +1 -0
  262. package/dist/root.js +148 -0
  263. package/dist/root.js.map +1 -0
  264. package/package.json +65 -0
  265. package/skills/meshy-cli/SKILL.md +99 -0
@@ -0,0 +1,374 @@
1
+ /**
2
+ * OAuth 2.0 Device Authorization Grant (RFC 8628) helpers.
3
+ *
4
+ * Implements:
5
+ * - deviceAuthorization(): POST /oauth/device_authorization
6
+ * - pollDeviceToken(): polling loop for /oauth/token with device_code grant
7
+ * - ensureRequestedScopesGranted(): scope verification
8
+ */
9
+ import { HintedError } from "./errors.js";
10
+ import { USER_AGENT } from "./user-agent.js";
11
+ // ---------------------------------------------------------------------------
12
+ // Error classes
13
+ // ---------------------------------------------------------------------------
14
+ /**
15
+ * Thrown when the /oauth/device_authorization endpoint returns 404.
16
+ * Indicates the meshyd deployment does not support device flow yet.
17
+ */
18
+ export class DeviceFlowNotSupportedError extends HintedError {
19
+ constructor() {
20
+ super({
21
+ // Do NOT suggest --manual here: a meshyd old enough to lack
22
+ // device_authorization also lacks the OOB display branch that --manual
23
+ // depends on, so that flag would fail too. Only safe options are to
24
+ // wait for the backend deployment or use an API key.
25
+ message: "This Meshy API host does not support device login yet — retry after backend deployment or use an API key (meshy auth login --with-key).",
26
+ code: "device_flow_not_supported",
27
+ hint: "Run: meshy auth login --with-key msy_...",
28
+ });
29
+ this.name = "DeviceFlowNotSupportedError";
30
+ }
31
+ }
32
+ /**
33
+ * An error from the device token polling endpoint that carries the machine
34
+ * error code from the OAuth response body.
35
+ */
36
+ export class DeviceFlowError extends HintedError {
37
+ oauthErrorCode;
38
+ constructor(params) {
39
+ super({ message: params.message, code: params.code, hint: params.hint });
40
+ this.name = "DeviceFlowError";
41
+ this.oauthErrorCode = params.oauthErrorCode;
42
+ }
43
+ }
44
+ // ---------------------------------------------------------------------------
45
+ // Device authorization request
46
+ // ---------------------------------------------------------------------------
47
+ const REQUEST_TIMEOUT_MS = 30_000;
48
+ /**
49
+ * POST /oauth/device_authorization to start a device flow.
50
+ *
51
+ * @throws DeviceFlowNotSupportedError on 404
52
+ * @throws HintedError on other non-200 responses
53
+ */
54
+ export async function deviceAuthorization(baseUrlV1, scope) {
55
+ const url = `${baseUrlV1}/oauth/device_authorization`;
56
+ let res;
57
+ try {
58
+ res = await fetch(url, {
59
+ method: "POST",
60
+ headers: {
61
+ "Content-Type": "application/json",
62
+ Accept: "application/json",
63
+ "User-Agent": USER_AGENT,
64
+ },
65
+ body: JSON.stringify({
66
+ client_id: "meshy-cli",
67
+ ...(scope ? { scope } : {}),
68
+ }),
69
+ signal: AbortSignal.timeout(REQUEST_TIMEOUT_MS),
70
+ });
71
+ }
72
+ catch (err) {
73
+ throw new HintedError({
74
+ message: `Network error contacting device authorization endpoint: ${err instanceof Error ? err.message : String(err)}`,
75
+ code: "oauth_network",
76
+ hint: "Run: meshy auth login --with-key msy_...",
77
+ });
78
+ }
79
+ if (res.status === 404) {
80
+ throw new DeviceFlowNotSupportedError();
81
+ }
82
+ let parsed;
83
+ try {
84
+ parsed = await res.json();
85
+ }
86
+ catch {
87
+ throw new HintedError({
88
+ message: `Device authorization endpoint returned non-JSON (status ${res.status})`,
89
+ code: "oauth_bad_response",
90
+ hint: "Run: meshy auth login",
91
+ });
92
+ }
93
+ if (!res.ok) {
94
+ const obj = parsed;
95
+ const msg = (typeof obj["error_description"] === "string" ? obj["error_description"] : undefined) ??
96
+ (typeof obj["message"] === "string" ? obj["message"] : undefined) ??
97
+ (typeof obj["error"] === "string" ? obj["error"] : undefined) ??
98
+ `Device authorization endpoint error (status ${res.status})`;
99
+ throw new HintedError({
100
+ message: msg,
101
+ code: "oauth_device_error",
102
+ hint: "Run: meshy auth login",
103
+ });
104
+ }
105
+ const obj = parsed;
106
+ // Validate required fields.
107
+ if (typeof obj["device_code"] !== "string" || !obj["device_code"]) {
108
+ throw new HintedError({
109
+ message: "Device authorization response missing device_code",
110
+ code: "oauth_bad_response",
111
+ hint: "Run: meshy auth login",
112
+ });
113
+ }
114
+ if (typeof obj["user_code"] !== "string" || !obj["user_code"]) {
115
+ throw new HintedError({
116
+ message: "Device authorization response missing user_code",
117
+ code: "oauth_bad_response",
118
+ hint: "Run: meshy auth login",
119
+ });
120
+ }
121
+ if (typeof obj["verification_uri"] !== "string" || !obj["verification_uri"]) {
122
+ throw new HintedError({
123
+ message: "Device authorization response missing verification_uri",
124
+ code: "oauth_bad_response",
125
+ hint: "Run: meshy auth login",
126
+ });
127
+ }
128
+ const rawInterval = typeof obj["interval"] === "number" ? obj["interval"] : 5;
129
+ const interval = rawInterval < 1 ? 5 : rawInterval;
130
+ const expiresIn = typeof obj["expires_in"] === "number" && obj["expires_in"] > 0 ? obj["expires_in"] : 600;
131
+ return {
132
+ device_code: obj["device_code"],
133
+ user_code: obj["user_code"],
134
+ verification_uri: obj["verification_uri"],
135
+ verification_uri_complete: typeof obj["verification_uri_complete"] === "string"
136
+ ? obj["verification_uri_complete"]
137
+ : obj["verification_uri"],
138
+ expires_in: expiresIn,
139
+ interval,
140
+ };
141
+ }
142
+ // ---------------------------------------------------------------------------
143
+ // Device token polling
144
+ // ---------------------------------------------------------------------------
145
+ /** Sleep for `ms` milliseconds. */
146
+ function sleep(ms) {
147
+ return new Promise((resolve) => setTimeout(resolve, ms));
148
+ }
149
+ /**
150
+ * POST /oauth/token with grant_type=device_code once and return the result.
151
+ * Returns the parsed body (success or error) and the HTTP status.
152
+ */
153
+ async function deviceTokenOnce(baseUrlV1, deviceCode) {
154
+ const url = `${baseUrlV1}/oauth/token`;
155
+ let res;
156
+ try {
157
+ res = await fetch(url, {
158
+ method: "POST",
159
+ headers: {
160
+ "Content-Type": "application/json",
161
+ Accept: "application/json",
162
+ "User-Agent": USER_AGENT,
163
+ },
164
+ body: JSON.stringify({
165
+ grant_type: "urn:ietf:params:oauth:grant-type:device_code",
166
+ device_code: deviceCode,
167
+ client_id: "meshy-cli",
168
+ }),
169
+ signal: AbortSignal.timeout(REQUEST_TIMEOUT_MS),
170
+ });
171
+ }
172
+ catch (err) {
173
+ throw new HintedError({
174
+ message: `Network error polling device token: ${err instanceof Error ? err.message : String(err)}`,
175
+ code: "oauth_network",
176
+ hint: "Run: meshy auth login",
177
+ });
178
+ }
179
+ let body;
180
+ try {
181
+ body = (await res.json());
182
+ }
183
+ catch {
184
+ throw new HintedError({
185
+ message: `Device token endpoint returned non-JSON (status ${res.status})`,
186
+ code: "oauth_bad_response",
187
+ hint: "Run: meshy auth login",
188
+ });
189
+ }
190
+ return { status: res.status, body };
191
+ }
192
+ /** Validate and extract a TokenResponse from a successful device token body. */
193
+ function extractTokenResponse(body) {
194
+ if (typeof body["access_token"] !== "string" || !body["access_token"]) {
195
+ throw new HintedError({
196
+ message: "Device token response missing access_token",
197
+ code: "oauth_bad_response",
198
+ hint: "Run: meshy auth login",
199
+ });
200
+ }
201
+ if (typeof body["token_type"] !== "string" ||
202
+ body["token_type"].toLowerCase() !== "bearer") {
203
+ throw new HintedError({
204
+ message: `Device token response has unexpected token_type: ${JSON.stringify(body["token_type"])}`,
205
+ code: "oauth_bad_response",
206
+ hint: "Run: meshy auth login",
207
+ });
208
+ }
209
+ const expiresIn = body["expires_in"];
210
+ if (typeof expiresIn !== "number" || !Number.isFinite(expiresIn) || expiresIn <= 0) {
211
+ throw new HintedError({
212
+ message: `Device token response has invalid expires_in: ${JSON.stringify(expiresIn)}`,
213
+ code: "oauth_bad_response",
214
+ hint: "Run: meshy auth login",
215
+ });
216
+ }
217
+ if (typeof body["refresh_token"] !== "string" || !body["refresh_token"]) {
218
+ throw new HintedError({
219
+ message: "Device token response missing refresh_token",
220
+ code: "oauth_bad_response",
221
+ hint: "Run: meshy auth login",
222
+ });
223
+ }
224
+ return {
225
+ access_token: body["access_token"],
226
+ token_type: body["token_type"],
227
+ expires_in: expiresIn,
228
+ refresh_token: body["refresh_token"],
229
+ scope: typeof body["scope"] === "string" ? body["scope"] : undefined,
230
+ user_id: typeof body["user_id"] === "string" ? body["user_id"] : undefined,
231
+ };
232
+ }
233
+ const MAX_INTERVAL_S = 60;
234
+ /**
235
+ * Poll the device token endpoint until the user approves, denies, or the
236
+ * token expires.
237
+ *
238
+ * Implements RFC 8628 §3.5 polling semantics:
239
+ * - authorization_pending → wait current interval
240
+ * - slow_down or HTTP 429 → interval += 5s (capped at 60s), wait
241
+ * - expired_token or deadline exceeded → throw oauth_timeout
242
+ * - access_denied → throw AUTH error
243
+ * - invalid_grant → throw AUTH error (already consumed)
244
+ * - 5xx / network → retry up to 3 consecutive, then throw
245
+ */
246
+ export async function pollDeviceToken(baseUrlV1, deviceCode, opts) {
247
+ const deadline = opts.deadline ?? Date.now() + opts.expiresIn * 1000;
248
+ let intervalMs = (opts.interval < 1 ? 5 : opts.interval) * 1000;
249
+ /** Consecutive network-level errors (thrown by deviceTokenOnce). */
250
+ let consecutiveNetworkErrors = 0;
251
+ /** Consecutive 5xx HTTP errors. */
252
+ let consecutive5xxErrors = 0;
253
+ for (;;) {
254
+ if (Date.now() >= deadline) {
255
+ throw new HintedError({
256
+ message: "Device flow timed out waiting for authorization. Run: meshy auth login",
257
+ code: "oauth_timeout",
258
+ hint: "Run: meshy auth login",
259
+ });
260
+ }
261
+ let result;
262
+ try {
263
+ result = await deviceTokenOnce(baseUrlV1, deviceCode);
264
+ consecutiveNetworkErrors = 0;
265
+ }
266
+ catch (err) {
267
+ consecutiveNetworkErrors++;
268
+ if (consecutiveNetworkErrors >= 3) {
269
+ throw err;
270
+ }
271
+ await sleep(intervalMs);
272
+ continue;
273
+ }
274
+ const { status, body } = result;
275
+ // Success.
276
+ if (status === 200) {
277
+ consecutive5xxErrors = 0;
278
+ return extractTokenResponse(body);
279
+ }
280
+ // Parse the OAuth error code from the body.
281
+ const oauthError = typeof body["error"] === "string" ? body["error"] : undefined;
282
+ const humanMsg = (typeof body["error_description"] === "string" ? body["error_description"] : undefined) ??
283
+ (typeof body["message"] === "string" ? body["message"] : undefined) ??
284
+ oauthError ??
285
+ `Device token error (status ${status})`;
286
+ // Handle specific OAuth error codes.
287
+ if (oauthError === "authorization_pending") {
288
+ consecutive5xxErrors = 0;
289
+ opts.onPending?.();
290
+ await sleep(intervalMs);
291
+ continue;
292
+ }
293
+ if (oauthError === "slow_down" || status === 429) {
294
+ consecutive5xxErrors = 0;
295
+ intervalMs = Math.min(intervalMs + 5000, MAX_INTERVAL_S * 1000);
296
+ await sleep(intervalMs);
297
+ continue;
298
+ }
299
+ if (oauthError === "expired_token") {
300
+ // Use DeviceFlowError so oauthErrorCode:"expired_token" survives to
301
+ // --json output, letting machine consumers distinguish this from
302
+ // access_denied / invalid_grant. Exit code stays TIMED_OUT (the
303
+ // "oauth_timeout" code maps there in exitCodeFor).
304
+ throw new DeviceFlowError({
305
+ message: "Device flow authorization code expired. Run: meshy auth login",
306
+ code: "oauth_timeout",
307
+ oauthErrorCode: "expired_token",
308
+ hint: "Run: meshy auth login",
309
+ });
310
+ }
311
+ if (oauthError === "access_denied") {
312
+ throw new DeviceFlowError({
313
+ message: "Device login was denied by the user.",
314
+ code: "oauth_access_denied",
315
+ oauthErrorCode: "access_denied",
316
+ hint: "Run: meshy auth login",
317
+ });
318
+ }
319
+ if (oauthError === "invalid_grant") {
320
+ throw new DeviceFlowError({
321
+ message: "Device flow already consumed or invalid; restart login.",
322
+ code: "oauth_invalid_grant",
323
+ oauthErrorCode: "invalid_grant",
324
+ hint: "Run: meshy auth login",
325
+ });
326
+ }
327
+ // 5xx errors: retry up to 3 consecutive, then surface.
328
+ if (status >= 500) {
329
+ consecutive5xxErrors++;
330
+ if (consecutive5xxErrors >= 3) {
331
+ throw new HintedError({
332
+ message: `Device token server error (status ${status}): ${humanMsg}`,
333
+ code: "oauth_server_error",
334
+ hint: "Run: meshy auth login",
335
+ });
336
+ }
337
+ await sleep(intervalMs);
338
+ continue;
339
+ }
340
+ // Other 400-level errors.
341
+ throw new HintedError({
342
+ message: humanMsg,
343
+ code: "oauth_device_error",
344
+ hint: "Run: meshy auth login",
345
+ });
346
+ }
347
+ }
348
+ // ---------------------------------------------------------------------------
349
+ // Scope verification
350
+ // ---------------------------------------------------------------------------
351
+ /**
352
+ * Verify that all requested scopes were granted.
353
+ *
354
+ * Both `requested` and `granted` are space-separated scope strings.
355
+ * Today both are "" — this trivially passes. Implemented generically for
356
+ * future use.
357
+ *
358
+ * @throws HintedError listing missing scopes if any requested scope is absent.
359
+ */
360
+ export function ensureRequestedScopesGranted(requested, granted) {
361
+ const requestedScopes = requested.split(/\s+/).filter(Boolean);
362
+ if (requestedScopes.length === 0)
363
+ return;
364
+ const grantedScopes = new Set((granted ?? "").split(/\s+/).filter(Boolean));
365
+ const missing = requestedScopes.filter((s) => !grantedScopes.has(s));
366
+ if (missing.length > 0) {
367
+ throw new HintedError({
368
+ message: `The following requested scopes were not granted: ${missing.join(", ")}`,
369
+ code: "oauth_scope_denied",
370
+ hint: "Run: meshy auth login",
371
+ });
372
+ }
373
+ }
374
+ //# sourceMappingURL=device.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"device.js","sourceRoot":"","sources":["../../src/internal/device.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Download a completed task's artifacts to the local filesystem.
3
+ *
4
+ * Two target shapes:
5
+ * 1. File path (e.g. `character/front.jpeg`) — used when the task has a
6
+ * single downloadable artifact (most 2D image tasks). The Content-Type
7
+ * of the HTTP response is authoritative; if the user-supplied extension
8
+ * disagrees, the file is saved with the correct extension instead.
9
+ * 2. Directory path (anything without a recognized file extension) — used
10
+ * when the task emits multiple artifacts (3D models, thumbnails,
11
+ * textures, animation outputs). Each artifact is named after its role
12
+ * (model.glb, thumbnail.png, texture_0_base_color.png, ...).
13
+ *
14
+ * A `meta.json` alongside the artifacts records the full task response plus
15
+ * the saved paths for later reference.
16
+ */
17
+ import type { Task } from "../client/types.js";
18
+ export interface Artifact {
19
+ /** Stable slot name ("model_glb", "image_0", "texture_0_base_color", ...) */
20
+ key: string;
21
+ /** Source URL (presigned). */
22
+ url: string;
23
+ /** Expected extension inferred from the slot name (no dot, may be empty). */
24
+ preferredExt: string;
25
+ }
26
+ export declare function enumerateArtifacts(task: Task): Artifact[];
27
+ /** Heuristic: does this look like a file path (has an extension) or a dir? */
28
+ export declare function looksLikeFile(path: string): boolean;
29
+ export interface DownloadResult {
30
+ savedFiles: string[];
31
+ metadataPath: string;
32
+ }
33
+ export declare function downloadArtifacts(task: Task, outputPath: string, resource: string): Promise<DownloadResult>;
34
+ //# sourceMappingURL=download.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"download.d.ts","sourceRoot":"","sources":["../../src/internal/download.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAOH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,oBAAoB,CAAC;AAO/C,MAAM,WAAW,QAAQ;IACvB,6EAA6E;IAC7E,GAAG,EAAE,MAAM,CAAC;IACZ,8BAA8B;IAC9B,GAAG,EAAE,MAAM,CAAC;IACZ,6EAA6E;IAC7E,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,IAAI,GAAG,QAAQ,EAAE,CA4CzD;AAED,8EAA8E;AAC9E,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEnD;AAED,MAAM,WAAW,cAAc;IAC7B,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,wBAAsB,iBAAiB,CACrC,IAAI,EAAE,IAAI,EACV,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,cAAc,CAAC,CA6DzB"}