@lumerahq/cli 0.19.2 → 0.19.3-dev.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.
@@ -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
  loadEnv
6
6
  } from "./chunk-2CR762KB.js";
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-IPAIPW63.js").then((m) => m.plan(args.slice(1)));
222
+ await import("./resources-4IUZYKGX.js").then((m) => m.plan(args.slice(1)));
223
223
  break;
224
224
  case "apply":
225
- await import("./resources-IPAIPW63.js").then((m) => m.apply(args.slice(1)));
225
+ await import("./resources-4IUZYKGX.js").then((m) => m.apply(args.slice(1)));
226
226
  break;
227
227
  case "pull":
228
- await import("./resources-IPAIPW63.js").then((m) => m.pull(args.slice(1)));
228
+ await import("./resources-4IUZYKGX.js").then((m) => m.pull(args.slice(1)));
229
229
  break;
230
230
  case "destroy":
231
- await import("./resources-IPAIPW63.js").then((m) => m.destroy(args.slice(1)));
231
+ await import("./resources-4IUZYKGX.js").then((m) => m.destroy(args.slice(1)));
232
232
  break;
233
233
  case "list":
234
- await import("./resources-IPAIPW63.js").then((m) => m.list(args.slice(1)));
234
+ await import("./resources-4IUZYKGX.js").then((m) => m.list(args.slice(1)));
235
235
  break;
236
236
  case "show":
237
- await import("./resources-IPAIPW63.js").then((m) => m.show(args.slice(1)));
237
+ await import("./resources-4IUZYKGX.js").then((m) => m.show(args.slice(1)));
238
238
  break;
239
239
  case "diff":
240
- await import("./resources-IPAIPW63.js").then((m) => m.diff(args.slice(1)));
240
+ await import("./resources-4IUZYKGX.js").then((m) => m.diff(args.slice(1)));
241
241
  break;
242
242
  // Development
243
243
  case "dev":
244
- await import("./dev-EVREBGR6.js").then((m) => m.dev(args.slice(1)));
244
+ await import("./dev-5JMHMS4U.js").then((m) => m.dev(args.slice(1)));
245
245
  break;
246
246
  case "run":
247
247
  await import("./run-5ZOSPBGO.js").then((m) => m.run(args.slice(1)));
@@ -3,7 +3,7 @@ import {
3
3
  } from "./chunk-XDTWVFPE.js";
4
4
  import {
5
5
  deploy
6
- } from "./chunk-SU26C4GL.js";
6
+ } from "./chunk-53NOF33P.js";
7
7
  import {
8
8
  loadEnv
9
9
  } from "./chunk-2CR762KB.js";
@@ -148,13 +148,82 @@ function safePrintLint(warnings, projectRoot) {
148
148
  if (process.env.LUMERA_DEBUG) console.error("[lint] print failed:", err);
149
149
  }
150
150
  }
151
- function detectPackageManager() {
152
- for (const pm of ["bun", "pnpm", "yarn", "npm"]) {
153
- try {
154
- execFileSync(pm, ["--version"], { stdio: "ignore" });
155
- return pm;
156
- } catch {
151
+ var PACKAGE_MANAGERS = ["bun", "pnpm", "yarn", "npm"];
152
+ var PACKAGE_MANAGER_VALUE_FLAGS = /* @__PURE__ */ new Set(["--package-manager"]);
153
+ function isPackageManager(value) {
154
+ return PACKAGE_MANAGERS.includes(value);
155
+ }
156
+ function commandAvailable(command) {
157
+ try {
158
+ execFileSync(command, ["--version"], { stdio: "ignore" });
159
+ return true;
160
+ } catch {
161
+ return false;
162
+ }
163
+ }
164
+ function parsePackageManagerSpecifier(value) {
165
+ const raw = (value || "").trim();
166
+ if (!raw) return void 0;
167
+ const name = raw.split("@")[0];
168
+ return isPackageManager(name) ? name : void 0;
169
+ }
170
+ function packageManagerFromPackageJson(projectRoot) {
171
+ try {
172
+ const pkg = JSON.parse(readFileSync(join(projectRoot, "package.json"), "utf-8"));
173
+ return parsePackageManagerSpecifier(pkg.packageManager);
174
+ } catch {
175
+ return void 0;
176
+ }
177
+ }
178
+ function getFlagValue(args, name) {
179
+ const long = `--${name}`;
180
+ for (let i = 0; i < args.length; i++) {
181
+ const arg = args[i];
182
+ if (arg === long) {
183
+ const next = args[i + 1];
184
+ return next && !next.startsWith("-") ? next : void 0;
157
185
  }
186
+ if (arg.startsWith(`${long}=`)) {
187
+ return arg.slice(long.length + 1);
188
+ }
189
+ }
190
+ return void 0;
191
+ }
192
+ function getPositionalArgs(args) {
193
+ const out = [];
194
+ for (let i = 0; i < args.length; i++) {
195
+ const arg = args[i];
196
+ if (PACKAGE_MANAGER_VALUE_FLAGS.has(arg)) {
197
+ i++;
198
+ continue;
199
+ }
200
+ if (arg.startsWith("-")) continue;
201
+ out.push(arg);
202
+ }
203
+ return out;
204
+ }
205
+ function detectPackageManager(projectRoot, override) {
206
+ const requested = parsePackageManagerSpecifier(override || process.env.LUMERA_PACKAGE_MANAGER);
207
+ if (requested) {
208
+ if (!commandAvailable(requested)) {
209
+ throw new Error(`Package manager '${requested}' was requested but is not available on PATH`);
210
+ }
211
+ return requested;
212
+ }
213
+ const declared = packageManagerFromPackageJson(projectRoot);
214
+ if (declared && commandAvailable(declared)) return declared;
215
+ const lockfileManagers = [
216
+ { pm: "pnpm", file: "pnpm-lock.yaml" },
217
+ { pm: "bun", file: "bun.lockb" },
218
+ { pm: "bun", file: "bun.lock" },
219
+ { pm: "yarn", file: "yarn.lock" },
220
+ { pm: "npm", file: "package-lock.json" }
221
+ ];
222
+ for (const { pm, file } of lockfileManagers) {
223
+ if (existsSync(join(projectRoot, file)) && commandAvailable(pm)) return pm;
224
+ }
225
+ for (const pm of ["pnpm", "bun", "yarn", "npm"]) {
226
+ if (commandAvailable(pm)) return pm;
158
227
  }
159
228
  return "npm";
160
229
  }
@@ -434,6 +503,9 @@ ${pc2.dim("Resources:")}
434
503
  ${pc2.dim("Options:")}
435
504
  --yes, -y Skip confirmation prompt (for CI/CD)
436
505
  --skip-build Skip build step when applying app
506
+ --no-app Apply resources only; do not build/deploy the app
507
+ --resources-only Alias for --no-app
508
+ --package-manager Package manager for app builds (pnpm, bun, yarn, npm)
437
509
 
438
510
  ${pc2.dim("Examples:")}
439
511
  lumera apply # Apply everything (shows plan, asks to confirm)
@@ -442,6 +514,8 @@ ${pc2.dim("Examples:")}
442
514
  lumera apply agents -y # Apply agents without confirmation
443
515
  lumera apply app # Deploy frontend
444
516
  lumera apply app --skip-build # Deploy without rebuilding
517
+ lumera apply --no-app -y # Apply resources without app build/deploy
518
+ lumera apply app --package-manager pnpm
445
519
  `);
446
520
  }
447
521
  function showPullHelp() {
@@ -1390,7 +1464,7 @@ async function applyApp(args) {
1390
1464
  if (!skipBuild) {
1391
1465
  console.log(pc2.dim(" Building..."));
1392
1466
  try {
1393
- const pm = detectPackageManager();
1467
+ const pm = detectPackageManager(projectRoot, getFlagValue(args, "package-manager"));
1394
1468
  execSync(`${pm} run build`, { cwd: projectRoot, stdio: "inherit" });
1395
1469
  } catch {
1396
1470
  throw new Error("Build failed");
@@ -2494,9 +2568,13 @@ async function apply(args) {
2494
2568
  const appName = getAppName(projectRoot);
2495
2569
  const api = createApiClient(void 0, void 0, appName);
2496
2570
  const projectId = getProjectId(projectRoot);
2497
- const positionalArgs = args.filter((a) => !a.startsWith("-"));
2571
+ const positionalArgs = getPositionalArgs(args);
2498
2572
  const { type, name } = parseResource(positionalArgs[0]);
2499
2573
  const autoConfirm = args.includes("--yes") || args.includes("-y") || !!process.env.CI;
2574
+ const skipApp = args.includes("--no-app") || args.includes("--resources-only");
2575
+ if (type === "app" && skipApp) {
2576
+ throw new Error("Cannot combine app resource with --no-app / --resources-only");
2577
+ }
2500
2578
  if (type === "app") {
2501
2579
  console.log();
2502
2580
  console.log(pc2.cyan(pc2.bold(" Apply")));
@@ -2537,7 +2615,7 @@ async function apply(args) {
2537
2615
  }
2538
2616
  }
2539
2617
  let willDeployApp = false;
2540
- if (!type) {
2618
+ if (!type && !skipApp) {
2541
2619
  try {
2542
2620
  if (existsSync(join(projectRoot, "dist")) || existsSync(join(projectRoot, "src"))) {
2543
2621
  willDeployApp = true;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lumerahq/cli",
3
- "version": "0.19.2",
3
+ "version": "0.19.3-dev.0",
4
4
  "description": "CLI for building and deploying Lumera apps",
5
5
  "type": "module",
6
6
  "engines": {