@lumerahq/cli 0.18.10 → 0.18.12

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.
@@ -52,7 +52,8 @@ async function fetchUserInfo(token) {
52
52
  try {
53
53
  const response = await fetchWithRetry(`${baseUrl}/api/me`, {
54
54
  headers: {
55
- Authorization: `Bearer ${token}`
55
+ Authorization: `Bearer ${token}`,
56
+ "X-Lumera-Client": "lumera-cli"
56
57
  }
57
58
  });
58
59
  if (!response.ok) {
@@ -25,7 +25,9 @@ function hashContent(content) {
25
25
  async function fetchSkillsList() {
26
26
  const baseUrl = getBaseUrl();
27
27
  const skillsApiUrl = `${baseUrl}/api/public/skills`;
28
- const listRes = await fetchWithRetry(skillsApiUrl);
28
+ const listRes = await fetchWithRetry(skillsApiUrl, {
29
+ headers: { "X-Lumera-Client": "lumera-cli" }
30
+ });
29
31
  if (!listRes.ok) {
30
32
  throw new Error(`Failed to fetch skills list: ${listRes.status}`);
31
33
  }
@@ -34,7 +36,9 @@ async function fetchSkillsList() {
34
36
  async function fetchSkillContent(slug) {
35
37
  const baseUrl = getBaseUrl();
36
38
  const skillsApiUrl = `${baseUrl}/api/public/skills`;
37
- const mdRes = await fetchWithRetry(`${skillsApiUrl}/${slug}.md`);
39
+ const mdRes = await fetchWithRetry(`${skillsApiUrl}/${slug}.md`, {
40
+ headers: { "X-Lumera-Client": "lumera-cli" }
41
+ });
38
42
  if (!mdRes.ok) {
39
43
  return null;
40
44
  }
@@ -52,6 +52,7 @@ var ApiClient = class {
52
52
  "Content-Type": "application/json",
53
53
  Authorization: `Bearer ${this.token}`,
54
54
  "User-Agent": CLI_USER_AGENT,
55
+ "X-Lumera-Client": "lumera-cli",
55
56
  ...this.projectExternalId ? { "X-Lumera-Project": this.projectExternalId } : {},
56
57
  ...options.headers
57
58
  };
@@ -3,7 +3,7 @@ import {
3
3
  } from "./chunk-2CR762KB.js";
4
4
  import {
5
5
  createApiClient
6
- } from "./chunk-PPSLI2ZI.js";
6
+ } from "./chunk-IBE6ACPE.js";
7
7
  import {
8
8
  findProjectRoot,
9
9
  getAppName
@@ -53,7 +53,12 @@ async function ensureAppRecord(apiBase, token, appName, appTitle) {
53
53
  const filterParam = encodeURIComponent(JSON.stringify({ external_id: appName }));
54
54
  const searchRes = await fetchWithRetry(
55
55
  `${apiBase}/pb/collections/lm_custom_apps/records?filter=${filterParam}`,
56
- { headers: { Authorization: `Bearer ${token}` } }
56
+ {
57
+ headers: {
58
+ Authorization: `Bearer ${token}`,
59
+ "X-Lumera-Client": "lumera-cli"
60
+ }
61
+ }
57
62
  );
58
63
  if (!searchRes.ok) {
59
64
  throw new Error(`Failed to check app record: ${await searchRes.text()}`);
@@ -65,11 +70,12 @@ async function ensureAppRecord(apiBase, token, appName, appTitle) {
65
70
  hosting_type: "s3"
66
71
  };
67
72
  const endpoint = existing ? `${apiBase}/pb/collections/lm_custom_apps/records/${existing.id}` : `${apiBase}/pb/collections/lm_custom_apps/records`;
68
- const res = await fetch(endpoint, {
73
+ const res = await fetchWithRetry(endpoint, {
69
74
  method: existing ? "PATCH" : "POST",
70
75
  headers: {
71
76
  Authorization: `Bearer ${token}`,
72
- "Content-Type": "application/json"
77
+ "Content-Type": "application/json",
78
+ "X-Lumera-Client": "lumera-cli"
73
79
  },
74
80
  body: JSON.stringify(appData)
75
81
  });
@@ -98,9 +104,12 @@ async function deploy(options) {
98
104
  const formData = new FormData();
99
105
  formData.append("tarball", new Blob([new Uint8Array(tarball)]), "dist.tar.gz");
100
106
  formData.append("version", version);
101
- const res = await fetch(`${apiUrl}/custom-apps/${appName}/deploy`, {
107
+ const res = await fetchWithRetry(`${apiUrl}/custom-apps/${appName}/deploy`, {
102
108
  method: "POST",
103
- headers: { Authorization: `Bearer ${token}` },
109
+ headers: {
110
+ Authorization: `Bearer ${token}`,
111
+ "X-Lumera-Client": "lumera-cli"
112
+ },
104
113
  body: formData
105
114
  });
106
115
  if (!res.ok) {
@@ -142,6 +151,9 @@ function detectRunner(projectRoot) {
142
151
  return ["bunx"];
143
152
  }
144
153
  }
154
+ function getParentOrigin(apiUrl) {
155
+ return apiUrl.replace(/\/api\/?$/, "").replace(/\/$/, "");
156
+ }
145
157
  async function dev(options) {
146
158
  const {
147
159
  token,
@@ -153,6 +165,8 @@ async function dev(options) {
153
165
  apiUrl
154
166
  } = options;
155
167
  const projectRoot = process.cwd();
168
+ const parentOrigin = getParentOrigin(apiUrl);
169
+ const lumeraAppUrl = `${parentOrigin}/custom-app/${appName}?dev`;
156
170
  if (await isPortInUse(port)) {
157
171
  console.log(pc.yellow(` Dev server already running on port ${port}, skipping start.`));
158
172
  return;
@@ -169,7 +183,7 @@ async function dev(options) {
169
183
  console.log(pc.green(" Starting dev server..."));
170
184
  console.log();
171
185
  console.log(pc.cyan(pc.bold(" Open in Lumera (dev mode):")));
172
- console.log(pc.cyan(` https://app.lumerahq.com/custom-app/${appName}?dev`));
186
+ console.log(pc.cyan(` ${lumeraAppUrl}`));
173
187
  console.log();
174
188
  const safeEnvPrefixes = ["VITE_", "LUMERA_", "NODE_", "npm_"];
175
189
  const safeEnvKeys = ["PATH", "HOME", "USER", "SHELL", "TERM", "LANG", "LC_ALL", "TMPDIR", "TZ"];
@@ -192,13 +206,14 @@ async function dev(options) {
192
206
  stdio: "inherit",
193
207
  env: {
194
208
  ...filteredEnv,
195
- VITE_PARENT_ORIGIN: "https://app.lumerahq.com",
209
+ VITE_PARENT_ORIGIN: parentOrigin,
210
+ VITE_PARENT_ORIGINS: parentOrigin,
196
211
  VITE_LUMERA_PROJECT: appName
197
212
  }
198
213
  });
199
214
  setTimeout(() => {
200
215
  console.log();
201
- console.log(pc.cyan(pc.bold(` \u279C Lumera: https://app.lumerahq.com/custom-app/${appName}?dev`)));
216
+ console.log(pc.cyan(pc.bold(` \u279C Lumera: ${lumeraAppUrl}`)));
202
217
  }, 2e3);
203
218
  vite.on("close", (code) => {
204
219
  process.exit(code || 0);
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  deps,
3
3
  syncDeps
4
- } from "./chunk-NJWVSQEL.js";
4
+ } from "./chunk-MVUNFAVL.js";
5
5
  import "./chunk-2CR762KB.js";
6
- import "./chunk-PPSLI2ZI.js";
6
+ import "./chunk-IBE6ACPE.js";
7
7
  import "./chunk-ZH3NVYEQ.js";
8
8
  import "./chunk-FJFIWC7G.js";
9
9
  import "./chunk-PNKVD2UK.js";
@@ -1,12 +1,12 @@
1
1
  import {
2
2
  dev
3
- } from "./chunk-5EBNGMIE.js";
3
+ } from "./chunk-N4KKEYAI.js";
4
4
  import {
5
5
  loadEnv
6
6
  } from "./chunk-2CR762KB.js";
7
7
  import {
8
8
  createApiClient
9
- } from "./chunk-PPSLI2ZI.js";
9
+ } from "./chunk-IBE6ACPE.js";
10
10
  import {
11
11
  findProjectRoot,
12
12
  getApiUrl,
package/dist/index.js CHANGED
@@ -219,66 +219,66 @@ async function main() {
219
219
  switch (command) {
220
220
  // Resource commands
221
221
  case "plan":
222
- await import("./resources-SMMFWICR.js").then((m) => m.plan(args.slice(1)));
222
+ await import("./resources-3FCEEAYQ.js").then((m) => m.plan(args.slice(1)));
223
223
  break;
224
224
  case "apply":
225
- await import("./resources-SMMFWICR.js").then((m) => m.apply(args.slice(1)));
225
+ await import("./resources-3FCEEAYQ.js").then((m) => m.apply(args.slice(1)));
226
226
  break;
227
227
  case "pull":
228
- await import("./resources-SMMFWICR.js").then((m) => m.pull(args.slice(1)));
228
+ await import("./resources-3FCEEAYQ.js").then((m) => m.pull(args.slice(1)));
229
229
  break;
230
230
  case "destroy":
231
- await import("./resources-SMMFWICR.js").then((m) => m.destroy(args.slice(1)));
231
+ await import("./resources-3FCEEAYQ.js").then((m) => m.destroy(args.slice(1)));
232
232
  break;
233
233
  case "list":
234
- await import("./resources-SMMFWICR.js").then((m) => m.list(args.slice(1)));
234
+ await import("./resources-3FCEEAYQ.js").then((m) => m.list(args.slice(1)));
235
235
  break;
236
236
  case "show":
237
- await import("./resources-SMMFWICR.js").then((m) => m.show(args.slice(1)));
237
+ await import("./resources-3FCEEAYQ.js").then((m) => m.show(args.slice(1)));
238
238
  break;
239
239
  case "diff":
240
- await import("./resources-SMMFWICR.js").then((m) => m.diff(args.slice(1)));
240
+ await import("./resources-3FCEEAYQ.js").then((m) => m.diff(args.slice(1)));
241
241
  break;
242
242
  // Development
243
243
  case "dev":
244
- await import("./dev-B7K2DXCM.js").then((m) => m.dev(args.slice(1)));
244
+ await import("./dev-WWCJZIV4.js").then((m) => m.dev(args.slice(1)));
245
245
  break;
246
246
  case "run":
247
- await import("./run-SQM3OWD2.js").then((m) => m.run(args.slice(1)));
247
+ await import("./run-JZX3E4UX.js").then((m) => m.run(args.slice(1)));
248
248
  break;
249
249
  // Project
250
250
  case "init":
251
- await import("./init-PSYCZETD.js").then((m) => m.init(args.slice(1)));
251
+ await import("./init-F4UYW6LD.js").then((m) => m.init(args.slice(1)));
252
252
  break;
253
253
  case "register":
254
- await import("./register-NYC5WVGZ.js").then((m) => m.register(args.slice(1)));
254
+ await import("./register-QPUXYBZ7.js").then((m) => m.register(args.slice(1)));
255
255
  break;
256
256
  case "templates":
257
257
  await import("./templates-M3RDNDDY.js").then((m) => m.templates(subcommand, args.slice(2)));
258
258
  break;
259
259
  case "status":
260
- await import("./status-LP73L4IV.js").then((m) => m.status(args.slice(1)));
260
+ await import("./status-X7WQYX2L.js").then((m) => m.status(args.slice(1)));
261
261
  break;
262
262
  case "migrate":
263
263
  await import("./migrate-NCZKP7FM.js").then((m) => m.migrate(args.slice(1)));
264
264
  break;
265
265
  // Skills
266
266
  case "skills":
267
- await import("./skills-YWYBMOVO.js").then((m) => m.skills(subcommand, args.slice(2)));
267
+ await import("./skills-FBYZIK3M.js").then((m) => m.skills(subcommand, args.slice(2)));
268
268
  break;
269
269
  // Dependencies
270
270
  case "deps":
271
- await import("./deps-V24GK3KJ.js").then((m) => m.deps(args.slice(1)));
271
+ await import("./deps-AVTV7FP3.js").then((m) => m.deps(args.slice(1)));
272
272
  break;
273
273
  // Auth
274
274
  case "login":
275
- await import("./auth-PDTSQN7X.js").then((m) => m.login(args.slice(1)));
275
+ await import("./auth-NI7JTMJM.js").then((m) => m.login(args.slice(1)));
276
276
  break;
277
277
  case "logout":
278
- await import("./auth-PDTSQN7X.js").then((m) => m.logout(args.slice(1)));
278
+ await import("./auth-NI7JTMJM.js").then((m) => m.logout(args.slice(1)));
279
279
  break;
280
280
  case "whoami":
281
- await import("./auth-PDTSQN7X.js").then((m) => m.whoami());
281
+ await import("./auth-NI7JTMJM.js").then((m) => m.whoami());
282
282
  break;
283
283
  // Convenience aliases
284
284
  case "help":
@@ -1,13 +1,13 @@
1
1
  import {
2
2
  installAllSkills,
3
3
  syncClaudeMd
4
- } from "./chunk-CCP66T22.js";
4
+ } from "./chunk-AUYOTENF.js";
5
5
  import {
6
6
  spinner
7
7
  } from "./chunk-BHYDYR75.js";
8
8
  import {
9
9
  createApiClient
10
- } from "./chunk-PPSLI2ZI.js";
10
+ } from "./chunk-IBE6ACPE.js";
11
11
  import {
12
12
  getToken,
13
13
  init_auth,
@@ -6,7 +6,7 @@ import {
6
6
  } from "./chunk-BHYDYR75.js";
7
7
  import {
8
8
  createApiClient
9
- } from "./chunk-PPSLI2ZI.js";
9
+ } from "./chunk-IBE6ACPE.js";
10
10
  import {
11
11
  findProjectRoot,
12
12
  getAppName,
@@ -1,15 +1,15 @@
1
1
  import {
2
2
  syncDeps
3
- } from "./chunk-NJWVSQEL.js";
3
+ } from "./chunk-MVUNFAVL.js";
4
4
  import {
5
5
  deploy
6
- } from "./chunk-5EBNGMIE.js";
6
+ } from "./chunk-N4KKEYAI.js";
7
7
  import {
8
8
  loadEnv
9
9
  } from "./chunk-2CR762KB.js";
10
10
  import {
11
11
  createApiClient
12
- } from "./chunk-PPSLI2ZI.js";
12
+ } from "./chunk-IBE6ACPE.js";
13
13
  import {
14
14
  findProjectRoot,
15
15
  getApiUrl,
@@ -1873,7 +1873,12 @@ async function destroyApp(skipConfirm) {
1873
1873
  const filterParam = encodeURIComponent(JSON.stringify({ external_id: appName }));
1874
1874
  const searchRes = await fetchWithRetry(
1875
1875
  `${apiUrl}/api/pb/collections/lm_custom_apps/records?filter=${filterParam}`,
1876
- { headers: { Authorization: `Bearer ${token}` } }
1876
+ {
1877
+ headers: {
1878
+ Authorization: `Bearer ${token}`,
1879
+ "X-Lumera-Client": "lumera-cli"
1880
+ }
1881
+ }
1877
1882
  );
1878
1883
  if (!searchRes.ok) {
1879
1884
  throw new Error(`Failed to find app: ${await searchRes.text()}`);
@@ -1898,9 +1903,15 @@ async function destroyApp(skipConfirm) {
1898
1903
  return;
1899
1904
  }
1900
1905
  }
1901
- const deleteRes = await fetch(
1906
+ const deleteRes = await fetchWithRetry(
1902
1907
  `${apiUrl}/api/pb/collections/lm_custom_apps/records/${appRecord.id}`,
1903
- { method: "DELETE", headers: { Authorization: `Bearer ${token}` } }
1908
+ {
1909
+ method: "DELETE",
1910
+ headers: {
1911
+ Authorization: `Bearer ${token}`,
1912
+ "X-Lumera-Client": "lumera-cli"
1913
+ }
1914
+ }
1904
1915
  );
1905
1916
  if (!deleteRes.ok) {
1906
1917
  throw new Error(`Failed to delete app: ${await deleteRes.text()}`);
@@ -2064,7 +2075,12 @@ async function showResource(api, platformDir, resourceType, resourceName, appNam
2064
2075
  const filterParam = encodeURIComponent(JSON.stringify({ external_id: appName2 }));
2065
2076
  const searchRes = await fetchWithRetry(
2066
2077
  `${apiUrl}/api/pb/collections/lm_custom_apps/records?filter=${filterParam}`,
2067
- { headers: { Authorization: `Bearer ${token}` } }
2078
+ {
2079
+ headers: {
2080
+ Authorization: `Bearer ${token}`,
2081
+ "X-Lumera-Client": "lumera-cli"
2082
+ }
2083
+ }
2068
2084
  );
2069
2085
  if (searchRes.ok) {
2070
2086
  const data = await searchRes.json();
@@ -3,7 +3,7 @@ import {
3
3
  } from "./chunk-2CR762KB.js";
4
4
  import {
5
5
  createApiClient
6
- } from "./chunk-PPSLI2ZI.js";
6
+ } from "./chunk-IBE6ACPE.js";
7
7
  import {
8
8
  findProjectRoot,
9
9
  getApiUrl,
@@ -168,7 +168,8 @@ async function triggerAutomation(automationName, projectRoot, flags) {
168
168
  method: "POST",
169
169
  headers: {
170
170
  "Authorization": `Bearer ${token}`,
171
- "Content-Type": "application/json"
171
+ "Content-Type": "application/json",
172
+ "X-Lumera-Client": "lumera-cli"
172
173
  },
173
174
  body: JSON.stringify({
174
175
  automation_id: automation.id,
@@ -8,7 +8,7 @@ import {
8
8
  slugToDirName,
9
9
  slugToFilename,
10
10
  syncClaudeMd
11
- } from "./chunk-CCP66T22.js";
11
+ } from "./chunk-AUYOTENF.js";
12
12
  import "./chunk-ZH3NVYEQ.js";
13
13
  import "./chunk-FJFIWC7G.js";
14
14
  import "./chunk-PNKVD2UK.js";
@@ -23,7 +23,10 @@ async function validateToken(token) {
23
23
  const baseUrl = getBaseUrl();
24
24
  try {
25
25
  const response = await fetchWithRetry(`${baseUrl}/api/me`, {
26
- headers: { Authorization: `Bearer ${token}` }
26
+ headers: {
27
+ Authorization: `Bearer ${token}`,
28
+ "X-Lumera-Client": "lumera-cli"
29
+ }
27
30
  });
28
31
  if (!response.ok) {
29
32
  return { valid: false, error: `${response.status} ${response.statusText}` };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lumerahq/cli",
3
- "version": "0.18.10",
3
+ "version": "0.18.12",
4
4
  "description": "CLI for building and deploying Lumera apps",
5
5
  "type": "module",
6
6
  "engines": {