@lumerahq/cli 0.19.5 → 0.19.7

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.
@@ -137,19 +137,59 @@ function isPortInUse(port, host = "127.0.0.1") {
137
137
  });
138
138
  });
139
139
  }
140
- function detectRunner(projectRoot) {
141
- if (existsSync(resolve(projectRoot, "bun.lockb")) || existsSync(resolve(projectRoot, "bun.lock"))) {
142
- return ["bunx"];
143
- }
144
- if (existsSync(resolve(projectRoot, "pnpm-lock.yaml"))) {
145
- return ["pnpm", "exec"];
140
+ function commandAvailable(command) {
141
+ try {
142
+ execSync(`${command} --version`, { stdio: "ignore" });
143
+ return true;
144
+ } catch {
145
+ return false;
146
146
  }
147
+ }
148
+ function parsePackageManagerSpecifier(value) {
149
+ const raw = (value || "").trim();
150
+ if (!raw) return void 0;
151
+ const name = raw.split("@")[0];
152
+ return ["bun", "pnpm", "yarn", "npm"].includes(name) ? name : void 0;
153
+ }
154
+ function packageManagerFromPackageJson(projectRoot) {
147
155
  try {
148
- execSync("pnpm --version", { stdio: "ignore" });
149
- return ["pnpm", "exec"];
156
+ const pkg = JSON.parse(readFileSync(resolve(projectRoot, "package.json"), "utf-8"));
157
+ return parsePackageManagerSpecifier(pkg.packageManager);
150
158
  } catch {
151
- return ["bunx"];
159
+ return void 0;
160
+ }
161
+ }
162
+ function runnerForPackageManager(pm) {
163
+ if (pm === "pnpm") return ["pnpm", "exec"];
164
+ if (pm === "bun") return ["bunx"];
165
+ if (pm === "yarn") return ["yarn"];
166
+ return ["npx"];
167
+ }
168
+ function detectRunner(projectRoot) {
169
+ const requested = parsePackageManagerSpecifier(process.env.LUMERA_PACKAGE_MANAGER);
170
+ if (requested && commandAvailable(runnerForPackageManager(requested)[0])) {
171
+ return runnerForPackageManager(requested);
172
+ }
173
+ const declared = packageManagerFromPackageJson(projectRoot);
174
+ if (declared && commandAvailable(runnerForPackageManager(declared)[0])) {
175
+ return runnerForPackageManager(declared);
176
+ }
177
+ const lockfileManagers = [
178
+ { pm: "pnpm", file: "pnpm-lock.yaml" },
179
+ { pm: "bun", file: "bun.lockb" },
180
+ { pm: "bun", file: "bun.lock" },
181
+ { pm: "yarn", file: "yarn.lock" },
182
+ { pm: "npm", file: "package-lock.json" }
183
+ ];
184
+ for (const { pm, file } of lockfileManagers) {
185
+ const runner = runnerForPackageManager(pm);
186
+ if (existsSync(resolve(projectRoot, file)) && commandAvailable(runner[0])) return runner;
187
+ }
188
+ for (const pm of ["pnpm", "bun", "yarn", "npm"]) {
189
+ const runner = runnerForPackageManager(pm);
190
+ if (commandAvailable(runner[0])) return runner;
152
191
  }
192
+ return ["npx"];
153
193
  }
154
194
  function getParentOrigin(apiUrl) {
155
195
  return apiUrl.replace(/\/api\/?$/, "").replace(/\/$/, "");
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  dev
3
- } from "./chunk-SU26C4GL.js";
3
+ } from "./chunk-53NOF33P.js";
4
4
  import {
5
5
  projectResourceDepsEnabled,
6
6
  syncDeps
package/dist/index.js CHANGED
@@ -219,29 +219,29 @@ async function main() {
219
219
  switch (command) {
220
220
  // Resource commands
221
221
  case "plan":
222
- await import("./resources-UMGSN6QA.js").then((m) => m.plan(args.slice(1)));
222
+ await import("./resources-P7WAHOHR.js").then((m) => m.plan(args.slice(1)));
223
223
  break;
224
224
  case "apply":
225
- await import("./resources-UMGSN6QA.js").then((m) => m.apply(args.slice(1)));
225
+ await import("./resources-P7WAHOHR.js").then((m) => m.apply(args.slice(1)));
226
226
  break;
227
227
  case "pull":
228
- await import("./resources-UMGSN6QA.js").then((m) => m.pull(args.slice(1)));
228
+ await import("./resources-P7WAHOHR.js").then((m) => m.pull(args.slice(1)));
229
229
  break;
230
230
  case "destroy":
231
- await import("./resources-UMGSN6QA.js").then((m) => m.destroy(args.slice(1)));
231
+ await import("./resources-P7WAHOHR.js").then((m) => m.destroy(args.slice(1)));
232
232
  break;
233
233
  case "list":
234
- await import("./resources-UMGSN6QA.js").then((m) => m.list(args.slice(1)));
234
+ await import("./resources-P7WAHOHR.js").then((m) => m.list(args.slice(1)));
235
235
  break;
236
236
  case "show":
237
- await import("./resources-UMGSN6QA.js").then((m) => m.show(args.slice(1)));
237
+ await import("./resources-P7WAHOHR.js").then((m) => m.show(args.slice(1)));
238
238
  break;
239
239
  case "diff":
240
- await import("./resources-UMGSN6QA.js").then((m) => m.diff(args.slice(1)));
240
+ await import("./resources-P7WAHOHR.js").then((m) => m.diff(args.slice(1)));
241
241
  break;
242
242
  // Development
243
243
  case "dev":
244
- await import("./dev-LDLUZ2VO.js").then((m) => m.dev(args.slice(1)));
244
+ await import("./dev-YYMFCXZ5.js").then((m) => m.dev(args.slice(1)));
245
245
  break;
246
246
  case "run":
247
247
  await import("./run-C23KZI4Z.js").then((m) => m.run(args.slice(1)));
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  deploy
3
- } from "./chunk-SU26C4GL.js";
3
+ } from "./chunk-53NOF33P.js";
4
4
  import {
5
5
  projectResourceDepsEnabled,
6
6
  syncDeps
@@ -272,13 +272,82 @@ function lintCollectionFiles(projectRoot, platformDir, filterName) {
272
272
  printLintWarnings(issues, projectRoot);
273
273
  throw new Error(`Found ${errors.length} collection lint error(s)`);
274
274
  }
275
- function detectPackageManager() {
276
- for (const pm of ["bun", "pnpm", "yarn", "npm"]) {
277
- try {
278
- execFileSync(pm, ["--version"], { stdio: "ignore" });
279
- return pm;
280
- } catch {
275
+ var PACKAGE_MANAGERS = ["bun", "pnpm", "yarn", "npm"];
276
+ var PACKAGE_MANAGER_VALUE_FLAGS = /* @__PURE__ */ new Set(["--package-manager"]);
277
+ function isPackageManager(value) {
278
+ return PACKAGE_MANAGERS.includes(value);
279
+ }
280
+ function commandAvailable(command) {
281
+ try {
282
+ execFileSync(command, ["--version"], { stdio: "ignore" });
283
+ return true;
284
+ } catch {
285
+ return false;
286
+ }
287
+ }
288
+ function parsePackageManagerSpecifier(value) {
289
+ const raw = (value || "").trim();
290
+ if (!raw) return void 0;
291
+ const name = raw.split("@")[0];
292
+ return isPackageManager(name) ? name : void 0;
293
+ }
294
+ function packageManagerFromPackageJson(projectRoot) {
295
+ try {
296
+ const pkg = JSON.parse(readFileSync2(join2(projectRoot, "package.json"), "utf-8"));
297
+ return parsePackageManagerSpecifier(pkg.packageManager);
298
+ } catch {
299
+ return void 0;
300
+ }
301
+ }
302
+ function getFlagValue(args, name) {
303
+ const long = `--${name}`;
304
+ for (let i = 0; i < args.length; i++) {
305
+ const arg = args[i];
306
+ if (arg === long) {
307
+ const next = args[i + 1];
308
+ return next && !next.startsWith("-") ? next : void 0;
281
309
  }
310
+ if (arg.startsWith(`${long}=`)) {
311
+ return arg.slice(long.length + 1);
312
+ }
313
+ }
314
+ return void 0;
315
+ }
316
+ function getPositionalArgs(args) {
317
+ const out = [];
318
+ for (let i = 0; i < args.length; i++) {
319
+ const arg = args[i];
320
+ if (PACKAGE_MANAGER_VALUE_FLAGS.has(arg)) {
321
+ i++;
322
+ continue;
323
+ }
324
+ if (arg.startsWith("-")) continue;
325
+ out.push(arg);
326
+ }
327
+ return out;
328
+ }
329
+ function detectPackageManager(projectRoot, override) {
330
+ const requested = parsePackageManagerSpecifier(override || process.env.LUMERA_PACKAGE_MANAGER);
331
+ if (requested) {
332
+ if (!commandAvailable(requested)) {
333
+ throw new Error(`Package manager '${requested}' was requested but is not available on PATH`);
334
+ }
335
+ return requested;
336
+ }
337
+ const declared = packageManagerFromPackageJson(projectRoot);
338
+ if (declared && commandAvailable(declared)) return declared;
339
+ const lockfileManagers = [
340
+ { pm: "pnpm", file: "pnpm-lock.yaml" },
341
+ { pm: "bun", file: "bun.lockb" },
342
+ { pm: "bun", file: "bun.lock" },
343
+ { pm: "yarn", file: "yarn.lock" },
344
+ { pm: "npm", file: "package-lock.json" }
345
+ ];
346
+ for (const { pm, file } of lockfileManagers) {
347
+ if (existsSync2(join2(projectRoot, file)) && commandAvailable(pm)) return pm;
348
+ }
349
+ for (const pm of ["pnpm", "bun", "yarn", "npm"]) {
350
+ if (commandAvailable(pm)) return pm;
282
351
  }
283
352
  return "npm";
284
353
  }
@@ -575,6 +644,9 @@ ${pc2.dim("Resources:")}
575
644
  ${pc2.dim("Options:")}
576
645
  --yes, -y Skip confirmation prompt (for CI/CD)
577
646
  --skip-build Skip build step when applying app
647
+ --no-app Apply resources only; do not build/deploy the app
648
+ --resources-only Alias for --no-app
649
+ --package-manager Package manager for app builds (pnpm, bun, yarn, npm)
578
650
 
579
651
  ${pc2.dim("Examples:")}
580
652
  lumera apply # Apply everything (shows plan, asks to confirm)
@@ -583,6 +655,8 @@ ${pc2.dim("Examples:")}
583
655
  lumera apply agents -y # Apply agents without confirmation
584
656
  lumera apply app # Deploy frontend
585
657
  lumera apply app --skip-build # Deploy without rebuilding
658
+ lumera apply --no-app -y # Apply resources without app build/deploy
659
+ lumera apply app --package-manager pnpm
586
660
  `);
587
661
  }
588
662
  function showPullHelp() {
@@ -1565,7 +1639,7 @@ async function applyApp(args) {
1565
1639
  if (!skipBuild) {
1566
1640
  console.log(pc2.dim(" Building..."));
1567
1641
  try {
1568
- const pm = detectPackageManager();
1642
+ const pm = detectPackageManager(projectRoot, getFlagValue(args, "package-manager"));
1569
1643
  execSync(`${pm} run build`, { cwd: projectRoot, stdio: "inherit" });
1570
1644
  } catch {
1571
1645
  throw new Error("Build failed");
@@ -2678,9 +2752,13 @@ async function apply(args) {
2678
2752
  const appName = getAppName(projectRoot);
2679
2753
  const api = createApiClient(void 0, void 0, appName);
2680
2754
  const projectId = getProjectId(projectRoot);
2681
- const positionalArgs = args.filter((a) => !a.startsWith("-"));
2755
+ const positionalArgs = getPositionalArgs(args);
2682
2756
  const { type, name } = parseResource(positionalArgs[0]);
2683
2757
  const autoConfirm = args.includes("--yes") || args.includes("-y") || !!process.env.CI;
2758
+ const skipApp = args.includes("--no-app") || args.includes("--resources-only");
2759
+ if (type === "app" && skipApp) {
2760
+ throw new Error("Cannot combine app resource with --no-app / --resources-only");
2761
+ }
2684
2762
  if (type === "app") {
2685
2763
  console.log();
2686
2764
  console.log(pc2.cyan(pc2.bold(" Apply")));
@@ -2723,7 +2801,7 @@ async function apply(args) {
2723
2801
  }
2724
2802
  }
2725
2803
  let willDeployApp = false;
2726
- if (!type) {
2804
+ if (!type && !skipApp) {
2727
2805
  try {
2728
2806
  if (existsSync2(join2(projectRoot, "dist")) || existsSync2(join2(projectRoot, "src"))) {
2729
2807
  willDeployApp = true;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lumerahq/cli",
3
- "version": "0.19.5",
3
+ "version": "0.19.7",
4
4
  "description": "CLI for building and deploying Lumera apps",
5
5
  "type": "module",
6
6
  "engines": {
@@ -49,11 +49,11 @@ For detailed technical reference (data models, relationships, design decisions),
49
49
 
50
50
  ### Installing components
51
51
 
52
- Use `bunx` to install shadcn components (the sandbox has `bun`, not `npm`/`npx`):
52
+ Install shadcn components with `pnpm dlx` (the sandbox's default JS package manager):
53
53
 
54
54
  ```bash
55
- bunx shadcn@latest add button card dialog # Install specific components
56
- bunx shadcn@latest add table input label select # Install more as needed
55
+ pnpm dlx shadcn@latest add button card dialog # Install specific components
56
+ pnpm dlx shadcn@latest add table input label select # Install more as needed
57
57
  ```
58
58
 
59
59
  Components install into `src/components/ui/` and are fully editable.