@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,297 @@
1
+ /**
2
+ * Credential store — the on-disk half of `meshy auth`.
3
+ *
4
+ * Layout: ~/.config/meshy/credentials.json, one file holding named profiles so
5
+ * a user can keep several accounts side by side. `~/.config` is used on every
6
+ * platform (including macOS, where the native spot would be Application
7
+ * Support) because the file is meant to be scriptable and dotfile-friendly.
8
+ *
9
+ * Non-production hosts get their own file — credentials.dev.json — so pointing
10
+ * MESHY_BASE_URL_V1 at staging cannot overwrite the production login, and
11
+ * logging out of one leaves the other alone.
12
+ *
13
+ * Every mutation runs under a cross-process lock and lands via a temp file +
14
+ * rename, because several agents driving this CLI in parallel is the normal
15
+ * case, not the exception.
16
+ *
17
+ * This module deliberately knows nothing about config.ts — it takes the base
18
+ * URL it needs as an argument, so config can depend on it and not vice versa.
19
+ */
20
+ import { chmodSync, closeSync, mkdirSync, openSync, readFileSync, renameSync, statSync, unlinkSync, writeFileSync, } from "node:fs";
21
+ import { homedir } from "node:os";
22
+ import { dirname, join } from "node:path";
23
+ export const AUTH_VERSION = 1;
24
+ export const DEFAULT_PROFILE = "default";
25
+ export const PROD_API_HOST = "api.meshy.ai";
26
+ const LOCK_TIMEOUT_MS = 30_000;
27
+ /** A lock older than this is assumed to be a crashed process's leftover. */
28
+ const LOCK_STALE_MS = 60_000;
29
+ /** Thrown when the file exists but cannot be understood — never on a missing file. */
30
+ export class CredentialsFileError extends Error {
31
+ path;
32
+ constructor(path, detail) {
33
+ super(`Invalid credentials file at ${path}: ${detail}`);
34
+ this.name = "CredentialsFileError";
35
+ this.path = path;
36
+ }
37
+ }
38
+ // ---------------------------------------------------------------------------
39
+ // Paths
40
+ // ---------------------------------------------------------------------------
41
+ /** Root config directory. MESHY_CONFIG_DIR wins when set. */
42
+ export function configDir(env = process.env) {
43
+ const override = env["MESHY_CONFIG_DIR"]?.trim();
44
+ if (override)
45
+ return override;
46
+ return join(homedir(), ".config", "meshy");
47
+ }
48
+ /**
49
+ * True when the given v1 base URL points somewhere other than production.
50
+ * An unparseable URL counts as non-production: a typo should not be able to
51
+ * touch the production credential file.
52
+ */
53
+ export function isNonProdBaseUrl(baseUrlV1) {
54
+ if (!baseUrlV1)
55
+ return false;
56
+ try {
57
+ return new URL(baseUrlV1).host !== PROD_API_HOST;
58
+ }
59
+ catch {
60
+ return true;
61
+ }
62
+ }
63
+ /**
64
+ * Resolves the credentials file path.
65
+ *
66
+ * MESHY_CREDENTIALS_PATH is absolute and wins over everything, including the
67
+ * prod/dev split — a caller that names a file gets that exact file.
68
+ */
69
+ export function credentialsPath(baseUrlV1, env = process.env) {
70
+ const explicit = env["MESHY_CREDENTIALS_PATH"]?.trim();
71
+ if (explicit)
72
+ return explicit;
73
+ const name = isNonProdBaseUrl(baseUrlV1) ? "credentials.dev.json" : "credentials.json";
74
+ return join(configDir(env), name);
75
+ }
76
+ function lockPathFor(file) {
77
+ return join(dirname(file), "locks", `${basenameOf(file)}.lock`);
78
+ }
79
+ function basenameOf(file) {
80
+ const parts = file.split(/[/\\]/);
81
+ return parts[parts.length - 1] || "credentials.json";
82
+ }
83
+ // ---------------------------------------------------------------------------
84
+ // Locking
85
+ // ---------------------------------------------------------------------------
86
+ function sleepSync(ms) {
87
+ // Blocking sleep without a busy loop; the store API is synchronous by design.
88
+ Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, ms);
89
+ }
90
+ /**
91
+ * Runs `fn` while holding an exclusive lock keyed to `file`.
92
+ *
93
+ * O_EXCL creation is the atomic primitive here — `flock` is not exposed by
94
+ * Node's fs module. A lock whose mtime is older than LOCK_STALE_MS is treated
95
+ * as abandoned and broken, so a killed process cannot wedge the CLI forever.
96
+ */
97
+ export function withCredentialsLock(file, fn) {
98
+ const lock = lockPathFor(file);
99
+ mkdirSync(dirname(lock), { recursive: true, mode: 0o700 });
100
+ const deadline = Date.now() + LOCK_TIMEOUT_MS;
101
+ let fd;
102
+ for (;;) {
103
+ try {
104
+ fd = openSync(lock, "wx", 0o600);
105
+ break;
106
+ }
107
+ catch (err) {
108
+ if (err.code !== "EEXIST")
109
+ throw err;
110
+ try {
111
+ if (Date.now() - statSync(lock).mtimeMs > LOCK_STALE_MS) {
112
+ unlinkSync(lock);
113
+ continue;
114
+ }
115
+ }
116
+ catch {
117
+ // The holder released it between open and stat — retry immediately.
118
+ continue;
119
+ }
120
+ if (Date.now() >= deadline) {
121
+ throw new Error(`timed out after ${LOCK_TIMEOUT_MS}ms waiting for the credentials lock at ${lock}. ` +
122
+ `If no other meshy process is running, delete that file.`);
123
+ }
124
+ sleepSync(25);
125
+ }
126
+ }
127
+ try {
128
+ return fn();
129
+ }
130
+ finally {
131
+ closeSync(fd);
132
+ try {
133
+ unlinkSync(lock);
134
+ }
135
+ catch {
136
+ /* already gone */
137
+ }
138
+ }
139
+ }
140
+ // ---------------------------------------------------------------------------
141
+ // Read / write
142
+ // ---------------------------------------------------------------------------
143
+ function emptyFile() {
144
+ return { auth_version: AUTH_VERSION, active_profile: DEFAULT_PROFILE, profiles: {} };
145
+ }
146
+ /**
147
+ * Reads the credentials file. Returns null when it does not exist — that is
148
+ * "not logged in", not an error. A file that exists but is unreadable throws
149
+ * CredentialsFileError so the user hears about it instead of silently falling
150
+ * back to "no credentials".
151
+ */
152
+ export function readCredentials(file) {
153
+ let raw;
154
+ try {
155
+ raw = readFileSync(file, "utf8");
156
+ }
157
+ catch (err) {
158
+ if (err.code === "ENOENT")
159
+ return null;
160
+ throw err;
161
+ }
162
+ let parsed;
163
+ try {
164
+ parsed = JSON.parse(raw);
165
+ }
166
+ catch (err) {
167
+ throw new CredentialsFileError(file, err instanceof Error ? err.message : "unparseable JSON");
168
+ }
169
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
170
+ throw new CredentialsFileError(file, "expected a JSON object");
171
+ }
172
+ const obj = parsed;
173
+ const profiles = obj["profiles"];
174
+ if (!profiles || typeof profiles !== "object" || Array.isArray(profiles)) {
175
+ throw new CredentialsFileError(file, "missing a 'profiles' object");
176
+ }
177
+ const active = typeof obj["active_profile"] === "string" ? obj["active_profile"] : DEFAULT_PROFILE;
178
+ const version = typeof obj["auth_version"] === "number" ? obj["auth_version"] : AUTH_VERSION;
179
+ return {
180
+ auth_version: version,
181
+ active_profile: active,
182
+ profiles: profiles,
183
+ };
184
+ }
185
+ /**
186
+ * Writes the file with 0600 via a temp file + rename, so a crash mid-write
187
+ * cannot leave a half-written credentials file behind. Callers that mutate
188
+ * existing state must hold the lock; see updateCredentials.
189
+ */
190
+ export function writeCredentials(state, file) {
191
+ mkdirSync(dirname(file), { recursive: true, mode: 0o700 });
192
+ const tmp = `${file}.${process.pid}.tmp`;
193
+ writeFileSync(tmp, `${JSON.stringify(state, null, 2)}\n`, { encoding: "utf8", mode: 0o600 });
194
+ try {
195
+ renameSync(tmp, file);
196
+ }
197
+ catch (err) {
198
+ try {
199
+ unlinkSync(tmp);
200
+ }
201
+ catch {
202
+ /* best effort */
203
+ }
204
+ throw err;
205
+ }
206
+ // rename preserves the temp file's mode, but an existing file's mode wins on
207
+ // some platforms — assert it either way.
208
+ chmodSync(file, 0o600);
209
+ }
210
+ /** Read-modify-write under the lock. The mutator may return a new state or mutate in place. */
211
+ export function updateCredentials(file, mutate) {
212
+ return withCredentialsLock(file, () => {
213
+ const current = readCredentials(file) ?? emptyFile();
214
+ const next = mutate(current) ?? current;
215
+ writeCredentials(next, file);
216
+ return next;
217
+ });
218
+ }
219
+ // ---------------------------------------------------------------------------
220
+ // Profile operations
221
+ // ---------------------------------------------------------------------------
222
+ export function saveProfile(file, name, profile, opts = {}) {
223
+ return updateCredentials(file, (state) => {
224
+ state.profiles[name] = { ...profile, created_at: profile.created_at ?? Date.now() };
225
+ if (opts.makeActive !== false)
226
+ state.active_profile = name;
227
+ });
228
+ }
229
+ /** Removes one profile. Returns false when it was not there to begin with. */
230
+ export function removeProfile(file, name) {
231
+ let existed = false;
232
+ updateCredentials(file, (state) => {
233
+ existed = Object.prototype.hasOwnProperty.call(state.profiles, name);
234
+ delete state.profiles[name];
235
+ if (state.active_profile === name) {
236
+ // Fall back to any remaining profile so the store never points at a
237
+ // profile that isn't there.
238
+ state.active_profile = Object.keys(state.profiles)[0] ?? DEFAULT_PROFILE;
239
+ }
240
+ });
241
+ return existed;
242
+ }
243
+ export function setActiveProfile(file, name) {
244
+ updateCredentials(file, (state) => {
245
+ if (!Object.prototype.hasOwnProperty.call(state.profiles, name)) {
246
+ throw new Error(`no such profile '${name}'. Run: meshy auth list`);
247
+ }
248
+ state.active_profile = name;
249
+ });
250
+ }
251
+ /** Deletes the whole file. Returns false when there was nothing to delete. */
252
+ export function deleteCredentialsFile(file) {
253
+ return withCredentialsLock(file, () => {
254
+ try {
255
+ unlinkSync(file);
256
+ return true;
257
+ }
258
+ catch (err) {
259
+ if (err.code === "ENOENT")
260
+ return false;
261
+ throw err;
262
+ }
263
+ });
264
+ }
265
+ /**
266
+ * Returns the usable secret from the active profile, or null when there is no
267
+ * file, no active profile, or the profile carries nothing usable.
268
+ */
269
+ export function resolveStoredCredential(file) {
270
+ const state = readCredentials(file);
271
+ if (!state)
272
+ return null;
273
+ const name = state.active_profile;
274
+ const profile = state.profiles[name];
275
+ if (!profile)
276
+ return null;
277
+ if (profile.kind === "api_key") {
278
+ if (!profile.api_key)
279
+ return null;
280
+ return { profile: name, kind: "api_key", apiKey: profile.api_key };
281
+ }
282
+ if (!profile.access_token)
283
+ return null;
284
+ return {
285
+ profile: name,
286
+ kind: "oauth",
287
+ accessToken: profile.access_token,
288
+ expiresAt: profile.expires_at,
289
+ };
290
+ }
291
+ /** `msy_abcd…wxyz` — enough to tell two keys apart, not enough to use one. */
292
+ export function maskSecret(secret) {
293
+ if (secret.length <= 12)
294
+ return `${secret.slice(0, 2)}…`;
295
+ return `${secret.slice(0, 8)}…${secret.slice(-4)}`;
296
+ }
297
+ //# sourceMappingURL=credentials.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"credentials.js","sourceRoot":"","sources":["../../src/internal/credentials.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,45 @@
1
+ /**
2
+ * Device flow state persistence — stores in-flight device flows so they can
3
+ * be resumed across process invocations (--no-wait → --device-flow <id>).
4
+ *
5
+ * Layout: ~/.config/meshy/device-flows.json, chmod 600.
6
+ * Uses the SAME O_EXCL lock + temp-rename pattern as credentials.ts.
7
+ *
8
+ * Each entry is keyed by a random flow_id (b64url 12 bytes = 16 chars).
9
+ * Expired entries are GC'd on every write.
10
+ */
11
+ export interface DeviceFlowEntry {
12
+ /** Random b64url 12-byte ID for this flow. */
13
+ flow_id: string;
14
+ device_code: string;
15
+ base_url_v1: string;
16
+ scope: string;
17
+ /** Polling interval in seconds. */
18
+ interval: number;
19
+ /** Unix ms when the device code expires. */
20
+ expires_at: number;
21
+ /** Unix ms when this entry was created. */
22
+ created_at: number;
23
+ user_code: string;
24
+ verification_uri_complete: string;
25
+ }
26
+ export declare function deviceFlowsPath(env?: NodeJS.ProcessEnv): string;
27
+ /** Generate a new random flow_id (b64url 12 bytes = 16 chars). */
28
+ export declare function generateFlowId(): string;
29
+ /**
30
+ * Save a device flow entry. GCs expired entries on write.
31
+ */
32
+ export declare function saveDeviceFlow(entry: DeviceFlowEntry, file?: string): void;
33
+ /**
34
+ * Load a device flow by flow_id. Returns null if not found or expired.
35
+ */
36
+ export declare function loadDeviceFlowByFlowId(flowId: string, file?: string): DeviceFlowEntry | null;
37
+ /**
38
+ * Load a device flow by device_code (scans all values). Returns null if not found or expired.
39
+ */
40
+ export declare function loadDeviceFlowByDeviceCode(deviceCode: string, file?: string): DeviceFlowEntry | null;
41
+ /**
42
+ * Delete a device flow by flow_id. No-op if not found.
43
+ */
44
+ export declare function deleteDeviceFlow(flowId: string, file?: string): void;
45
+ //# sourceMappingURL=device-state.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"device-state.d.ts","sourceRoot":"","sources":["../../src/internal/device-state.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAqBH,MAAM,WAAW,eAAe;IAC9B,8CAA8C;IAC9C,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,mCAAmC;IACnC,QAAQ,EAAE,MAAM,CAAC;IACjB,4CAA4C;IAC5C,UAAU,EAAE,MAAM,CAAC;IACnB,2CAA2C;IAC3C,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,yBAAyB,EAAE,MAAM,CAAC;CACnC;AAaD,wBAAgB,eAAe,CAAC,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,MAAM,CAE5E;AAqHD,kEAAkE;AAClE,wBAAgB,cAAc,IAAI,MAAM,CAEvC;AAED;;GAEG;AACH,wBAAgB,cAAc,CAC5B,KAAK,EAAE,eAAe,EACtB,IAAI,GAAE,MAA0B,GAC/B,IAAI,CAIN;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CACpC,MAAM,EAAE,MAAM,EACd,IAAI,GAAE,MAA0B,GAC/B,eAAe,GAAG,IAAI,CAMxB;AAED;;GAEG;AACH,wBAAgB,0BAA0B,CACxC,UAAU,EAAE,MAAM,EAClB,IAAI,GAAE,MAA0B,GAC/B,eAAe,GAAG,IAAI,CASxB;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,MAAM,EACd,IAAI,GAAE,MAA0B,GAC/B,IAAI,CAIN"}
@@ -0,0 +1,180 @@
1
+ /**
2
+ * Device flow state persistence — stores in-flight device flows so they can
3
+ * be resumed across process invocations (--no-wait → --device-flow <id>).
4
+ *
5
+ * Layout: ~/.config/meshy/device-flows.json, chmod 600.
6
+ * Uses the SAME O_EXCL lock + temp-rename pattern as credentials.ts.
7
+ *
8
+ * Each entry is keyed by a random flow_id (b64url 12 bytes = 16 chars).
9
+ * Expired entries are GC'd on every write.
10
+ */
11
+ import { chmodSync, closeSync, mkdirSync, openSync, readFileSync, renameSync, statSync, unlinkSync, writeFileSync, } from "node:fs";
12
+ import { randomBytes } from "node:crypto";
13
+ import { dirname, join } from "node:path";
14
+ import { configDir } from "./credentials.js";
15
+ // ---------------------------------------------------------------------------
16
+ // Paths and locking
17
+ // ---------------------------------------------------------------------------
18
+ const LOCK_TIMEOUT_MS = 30_000;
19
+ const LOCK_STALE_MS = 60_000;
20
+ export function deviceFlowsPath(env = process.env) {
21
+ return join(configDir(env), "device-flows.json");
22
+ }
23
+ function lockPathFor(file) {
24
+ const parts = file.split(/[/\\]/);
25
+ const base = parts[parts.length - 1] || "device-flows.json";
26
+ return join(dirname(file), "locks", `${base}.lock`);
27
+ }
28
+ function sleepSync(ms) {
29
+ Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, ms);
30
+ }
31
+ function withDeviceFlowsLock(file, fn) {
32
+ const lock = lockPathFor(file);
33
+ mkdirSync(dirname(lock), { recursive: true, mode: 0o700 });
34
+ const deadline = Date.now() + LOCK_TIMEOUT_MS;
35
+ let fd;
36
+ for (;;) {
37
+ try {
38
+ fd = openSync(lock, "wx", 0o600);
39
+ break;
40
+ }
41
+ catch (err) {
42
+ if (err.code !== "EEXIST")
43
+ throw err;
44
+ try {
45
+ if (Date.now() - statSync(lock).mtimeMs > LOCK_STALE_MS) {
46
+ unlinkSync(lock);
47
+ continue;
48
+ }
49
+ }
50
+ catch {
51
+ continue;
52
+ }
53
+ if (Date.now() >= deadline) {
54
+ throw new Error(`timed out after ${LOCK_TIMEOUT_MS}ms waiting for the device-flows lock at ${lock}. ` +
55
+ `If no other meshy process is running, delete that file.`);
56
+ }
57
+ sleepSync(25);
58
+ }
59
+ }
60
+ try {
61
+ return fn();
62
+ }
63
+ finally {
64
+ closeSync(fd);
65
+ try {
66
+ unlinkSync(lock);
67
+ }
68
+ catch {
69
+ /* already gone */
70
+ }
71
+ }
72
+ }
73
+ // ---------------------------------------------------------------------------
74
+ // Read / write
75
+ // ---------------------------------------------------------------------------
76
+ function readDeviceFlows(file) {
77
+ let raw;
78
+ try {
79
+ raw = readFileSync(file, "utf8");
80
+ }
81
+ catch (err) {
82
+ if (err.code === "ENOENT")
83
+ return { flows: {} };
84
+ throw err;
85
+ }
86
+ try {
87
+ const parsed = JSON.parse(raw);
88
+ if (!parsed || typeof parsed !== "object" || !parsed.flows)
89
+ return { flows: {} };
90
+ return parsed;
91
+ }
92
+ catch {
93
+ return { flows: {} };
94
+ }
95
+ }
96
+ function writeDeviceFlows(state, file) {
97
+ mkdirSync(dirname(file), { recursive: true, mode: 0o700 });
98
+ const tmp = `${file}.${process.pid}.tmp`;
99
+ writeFileSync(tmp, `${JSON.stringify(state, null, 2)}\n`, { encoding: "utf8", mode: 0o600 });
100
+ try {
101
+ renameSync(tmp, file);
102
+ }
103
+ catch (err) {
104
+ try {
105
+ unlinkSync(tmp);
106
+ }
107
+ catch {
108
+ /* best effort */
109
+ }
110
+ throw err;
111
+ }
112
+ chmodSync(file, 0o600);
113
+ }
114
+ /** GC expired entries. Mutates the state in place. */
115
+ function gcExpired(state) {
116
+ const now = Date.now();
117
+ for (const [id, entry] of Object.entries(state.flows)) {
118
+ if (entry.expires_at <= now) {
119
+ delete state.flows[id];
120
+ }
121
+ }
122
+ }
123
+ function updateDeviceFlows(file, mutate) {
124
+ return withDeviceFlowsLock(file, () => {
125
+ const current = readDeviceFlows(file);
126
+ gcExpired(current);
127
+ const result = mutate(current);
128
+ writeDeviceFlows(current, file);
129
+ return result;
130
+ });
131
+ }
132
+ // ---------------------------------------------------------------------------
133
+ // Public API
134
+ // ---------------------------------------------------------------------------
135
+ /** Generate a new random flow_id (b64url 12 bytes = 16 chars). */
136
+ export function generateFlowId() {
137
+ return randomBytes(12).toString("base64url");
138
+ }
139
+ /**
140
+ * Save a device flow entry. GCs expired entries on write.
141
+ */
142
+ export function saveDeviceFlow(entry, file = deviceFlowsPath()) {
143
+ updateDeviceFlows(file, (state) => {
144
+ state.flows[entry.flow_id] = entry;
145
+ });
146
+ }
147
+ /**
148
+ * Load a device flow by flow_id. Returns null if not found or expired.
149
+ */
150
+ export function loadDeviceFlowByFlowId(flowId, file = deviceFlowsPath()) {
151
+ const state = readDeviceFlows(file);
152
+ const entry = state.flows[flowId];
153
+ if (!entry)
154
+ return null;
155
+ if (entry.expires_at <= Date.now())
156
+ return null;
157
+ return entry;
158
+ }
159
+ /**
160
+ * Load a device flow by device_code (scans all values). Returns null if not found or expired.
161
+ */
162
+ export function loadDeviceFlowByDeviceCode(deviceCode, file = deviceFlowsPath()) {
163
+ const state = readDeviceFlows(file);
164
+ const now = Date.now();
165
+ for (const entry of Object.values(state.flows)) {
166
+ if (entry.device_code === deviceCode && entry.expires_at > now) {
167
+ return entry;
168
+ }
169
+ }
170
+ return null;
171
+ }
172
+ /**
173
+ * Delete a device flow by flow_id. No-op if not found.
174
+ */
175
+ export function deleteDeviceFlow(flowId, file = deviceFlowsPath()) {
176
+ updateDeviceFlows(file, (state) => {
177
+ delete state.flows[flowId];
178
+ });
179
+ }
180
+ //# sourceMappingURL=device-state.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"device-state.js","sourceRoot":"","sources":["../../src/internal/device-state.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,79 @@
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 type { TokenResponse } from "./oauth.js";
11
+ export interface DeviceAuthorizationResponse {
12
+ device_code: string;
13
+ user_code: string;
14
+ verification_uri: string;
15
+ verification_uri_complete: string;
16
+ expires_in: number;
17
+ interval: number;
18
+ }
19
+ export interface PollDeviceTokenOpts {
20
+ /** Initial polling interval in seconds (from server; clamped to ≥1 → 5). */
21
+ interval: number;
22
+ /** Token lifetime in seconds (from server). */
23
+ expiresIn: number;
24
+ /** Optional callback called on each authorization_pending response. */
25
+ onPending?: () => void;
26
+ /** Optional hard deadline override (unix ms). Defaults to now + expiresIn*1000. */
27
+ deadline?: number;
28
+ }
29
+ /**
30
+ * Thrown when the /oauth/device_authorization endpoint returns 404.
31
+ * Indicates the meshyd deployment does not support device flow yet.
32
+ */
33
+ export declare class DeviceFlowNotSupportedError extends HintedError {
34
+ constructor();
35
+ }
36
+ /**
37
+ * An error from the device token polling endpoint that carries the machine
38
+ * error code from the OAuth response body.
39
+ */
40
+ export declare class DeviceFlowError extends HintedError {
41
+ readonly oauthErrorCode: string;
42
+ constructor(params: {
43
+ message: string;
44
+ code: string;
45
+ oauthErrorCode: string;
46
+ hint?: string;
47
+ });
48
+ }
49
+ /**
50
+ * POST /oauth/device_authorization to start a device flow.
51
+ *
52
+ * @throws DeviceFlowNotSupportedError on 404
53
+ * @throws HintedError on other non-200 responses
54
+ */
55
+ export declare function deviceAuthorization(baseUrlV1: string, scope?: string): Promise<DeviceAuthorizationResponse>;
56
+ /**
57
+ * Poll the device token endpoint until the user approves, denies, or the
58
+ * token expires.
59
+ *
60
+ * Implements RFC 8628 §3.5 polling semantics:
61
+ * - authorization_pending → wait current interval
62
+ * - slow_down or HTTP 429 → interval += 5s (capped at 60s), wait
63
+ * - expired_token or deadline exceeded → throw oauth_timeout
64
+ * - access_denied → throw AUTH error
65
+ * - invalid_grant → throw AUTH error (already consumed)
66
+ * - 5xx / network → retry up to 3 consecutive, then throw
67
+ */
68
+ export declare function pollDeviceToken(baseUrlV1: string, deviceCode: string, opts: PollDeviceTokenOpts): Promise<TokenResponse>;
69
+ /**
70
+ * Verify that all requested scopes were granted.
71
+ *
72
+ * Both `requested` and `granted` are space-separated scope strings.
73
+ * Today both are "" — this trivially passes. Implemented generically for
74
+ * future use.
75
+ *
76
+ * @throws HintedError listing missing scopes if any requested scope is absent.
77
+ */
78
+ export declare function ensureRequestedScopesGranted(requested: string, granted: string | undefined): void;
79
+ //# sourceMappingURL=device.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"device.d.ts","sourceRoot":"","sources":["../../src/internal/device.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE1C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAMhD,MAAM,WAAW,2BAA2B;IAC1C,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,gBAAgB,EAAE,MAAM,CAAC;IACzB,yBAAyB,EAAE,MAAM,CAAC;IAClC,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,mBAAmB;IAClC,4EAA4E;IAC5E,QAAQ,EAAE,MAAM,CAAC;IACjB,+CAA+C;IAC/C,SAAS,EAAE,MAAM,CAAC;IAClB,uEAAuE;IACvE,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;IACvB,mFAAmF;IACnF,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAMD;;;GAGG;AACH,qBAAa,2BAA4B,SAAQ,WAAW;;CAc3D;AAED;;;GAGG;AACH,qBAAa,eAAgB,SAAQ,WAAW;IAC9C,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;gBAEpB,MAAM,EAAE;QAClB,OAAO,EAAE,MAAM,CAAC;QAChB,IAAI,EAAE,MAAM,CAAC;QACb,cAAc,EAAE,MAAM,CAAC;QACvB,IAAI,CAAC,EAAE,MAAM,CAAC;KACf;CAKF;AAQD;;;;;GAKG;AACH,wBAAsB,mBAAmB,CACvC,SAAS,EAAE,MAAM,EACjB,KAAK,CAAC,EAAE,MAAM,GACb,OAAO,CAAC,2BAA2B,CAAC,CAgGtC;AAwGD;;;;;;;;;;;GAWG;AACH,wBAAsB,eAAe,CACnC,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,mBAAmB,GACxB,OAAO,CAAC,aAAa,CAAC,CAkHxB;AAMD;;;;;;;;GAQG;AACH,wBAAgB,4BAA4B,CAC1C,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,GAAG,SAAS,GAC1B,IAAI,CAcN"}