@lunora/cli 1.0.0-alpha.53 → 1.0.0-alpha.55

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.
package/dist/index.d.mts CHANGED
@@ -498,6 +498,14 @@ interface DevRemotePlan {
498
498
  }
499
499
  interface DevCommandPlan {
500
500
  codegenEnabled: boolean;
501
+ /**
502
+ * One-line redirect hint printed when a Vite/meta-framework is detected: in
503
+ * those projects the worker runs *inside* Vite, so the user should run their
504
+ * framework dev script for the full app. `undefined` for a standalone project
505
+ * (no framework) — `lunora dev` is the right command there. Purely
506
+ * informational: the wrangler spawn runs regardless.
507
+ */
508
+ frameworkHint?: string;
501
509
  /** The remote-binding decision: which D1/KV/R2 bindings hit the deployed worker. */
502
510
  remote: DevRemotePlan;
503
511
  studioEnabled: boolean;
package/dist/index.d.ts CHANGED
@@ -498,6 +498,14 @@ interface DevRemotePlan {
498
498
  }
499
499
  interface DevCommandPlan {
500
500
  codegenEnabled: boolean;
501
+ /**
502
+ * One-line redirect hint printed when a Vite/meta-framework is detected: in
503
+ * those projects the worker runs *inside* Vite, so the user should run their
504
+ * framework dev script for the full app. `undefined` for a standalone project
505
+ * (no framework) — `lunora dev` is the right command there. Purely
506
+ * informational: the wrangler spawn runs regardless.
507
+ */
508
+ frameworkHint?: string;
501
509
  /** The remote-binding decision: which D1/KV/R2 bindings hit the deployed worker. */
502
510
  remote: DevRemotePlan;
503
511
  studioEnabled: boolean;
@@ -1,5 +1,6 @@
1
1
  import { readLinkedProject } from '@lunora/config';
2
2
  import { d as defineHandler } from '../packem_shared/command-D3lB_4Az.mjs';
3
+ import { e as execArgsFor, d as detectPackageManager } from '../packem_shared/detect-package-manager-Cxo6Tpyx.mjs';
3
4
  import { defaultSpawner } from '../packem_shared/createRecordingSpawner-DxI3mebw.mjs';
4
5
 
5
6
  const LOG_FORMATS = /* @__PURE__ */ new Set(["json", "pretty"]);
@@ -9,7 +10,7 @@ const runLogsCommand = async (options) => {
9
10
  options.logger.error(`logs: unknown --format "${options.format}" — expected pretty | json`);
10
11
  return { code: 1, descriptor: void 0, error: "invalid format" };
11
12
  }
12
- const args = ["exec", "wrangler", "tail"];
13
+ const args = ["tail"];
13
14
  if (options.worker !== void 0) {
14
15
  args.push(options.worker);
15
16
  }
@@ -29,9 +30,10 @@ const runLogsCommand = async (options) => {
29
30
  if (options.temporary) {
30
31
  args.push("--temporary");
31
32
  }
33
+ const exec = execArgsFor(detectPackageManager(cwd), "wrangler", args);
32
34
  const descriptor = {
33
- args,
34
- command: "pnpm",
35
+ args: exec.args,
36
+ command: exec.command,
35
37
  cwd
36
38
  };
37
39
  options.logger.info(`tailing logs via ${descriptor.command} ${descriptor.args.join(" ")}`);
@@ -2,6 +2,7 @@ import { mkdtempSync, rmSync, existsSync, readdirSync, statSync } from 'node:fs'
2
2
  import { tmpdir } from 'node:os';
3
3
  import { join, relative } from 'node:path';
4
4
  import { d as defineHandler } from '../packem_shared/command-D3lB_4Az.mjs';
5
+ import { e as execArgsFor, d as detectPackageManager } from '../packem_shared/detect-package-manager-Cxo6Tpyx.mjs';
5
6
  import { defaultSpawner } from '../packem_shared/createRecordingSpawner-DxI3mebw.mjs';
6
7
 
7
8
  const walk = (root) => {
@@ -71,9 +72,10 @@ const runAnalyzeCommand = async (options) => {
71
72
  } else {
72
73
  outdir = mkdtempSync(join(tmpdir(), "lunora-analyze-"));
73
74
  temporary = true;
75
+ const exec = execArgsFor(detectPackageManager(cwd), "wrangler", ["deploy", "--dry-run", "--outdir", outdir]);
74
76
  descriptor = {
75
- args: ["exec", "wrangler", "deploy", "--dry-run", "--outdir", outdir],
76
- command: "pnpm",
77
+ args: exec.args,
78
+ command: exec.command,
77
79
  cwd
78
80
  };
79
81
  logger.info(`analyze: building via ${descriptor.command} ${descriptor.args.join(" ")}`);
@@ -4,6 +4,7 @@ import { runCodegen } from '@lunora/codegen';
4
4
  import { p as parseApiSpec } from '../packem_shared/api-spec-CtA6ilu4.mjs';
5
5
  import { a as renderCodegenHint } from '../packem_shared/codegen-error-DJG-ghs_.mjs';
6
6
  import { d as defineHandler } from '../packem_shared/command-D3lB_4Az.mjs';
7
+ import { e as execArgsFor, d as detectPackageManager } from '../packem_shared/detect-package-manager-Cxo6Tpyx.mjs';
7
8
  import { v as validateOutputFormat, i as isJsonFormat, p as printJson, l as loggerForFormat } from '../packem_shared/output-format-wUvAN6AL.mjs';
8
9
  import { r as runSchemaDriftGate } from '../packem_shared/schema-drift-gate-BtBt0as0.mjs';
9
10
  import { defaultSpawner } from '../packem_shared/createRecordingSpawner-DxI3mebw.mjs';
@@ -13,7 +14,8 @@ const runTypecheckStep = async (cwd, spawner) => {
13
14
  if (!existsSync(join(cwd, "tsconfig.json"))) {
14
15
  return { warning: "no tsconfig.json found — skipping TypeScript type-check" };
15
16
  }
16
- const result = await spawner({ args: ["exec", "tsc", "--noEmit", "-p", "tsconfig.json"], command: "pnpm", cwd });
17
+ const exec = execArgsFor(detectPackageManager(cwd), "tsc", ["--noEmit", "-p", "tsconfig.json"]);
18
+ const result = await spawner({ args: exec.args, command: exec.command, cwd });
17
19
  return result.code === 0 ? {} : { error: `type errors: tsc --noEmit exited ${String(result.code)}` };
18
20
  };
19
21
  const reportVerifyResult = (logger, errors, warnings, wranglerPath) => {
@@ -1,4 +1,5 @@
1
1
  import { d as defineHandler } from '../packem_shared/command-D3lB_4Az.mjs';
2
+ import { e as execArgsFor, d as detectPackageManager } from '../packem_shared/detect-package-manager-Cxo6Tpyx.mjs';
2
3
  import { i as isDockerAvailable } from '../packem_shared/docker-hMQ97KSQ.mjs';
3
4
  import { defaultSpawner } from '../packem_shared/createRecordingSpawner-DxI3mebw.mjs';
4
5
 
@@ -18,7 +19,7 @@ const runContainersCommand = async (options) => {
18
19
  );
19
20
  return { code: 1 };
20
21
  }
21
- const args = ["exec", "wrangler", "containers", subcommand, ...rest];
22
+ const args = ["containers", subcommand, ...rest];
22
23
  if (options.tag !== void 0) {
23
24
  args.push("--tag", options.tag);
24
25
  }
@@ -28,7 +29,9 @@ const runContainersCommand = async (options) => {
28
29
  if (options.env !== void 0) {
29
30
  args.push("--env", options.env);
30
31
  }
31
- const descriptor = { args, command: "pnpm", cwd: options.cwd ?? process.cwd() };
32
+ const cwd = options.cwd ?? process.cwd();
33
+ const exec = execArgsFor(detectPackageManager(cwd), "wrangler", args);
34
+ const descriptor = { args: exec.args, command: exec.command, cwd };
32
35
  options.logger.info(`running ${descriptor.command} ${descriptor.args.join(" ")}`);
33
36
  const spawner = options.spawner ?? defaultSpawner;
34
37
  const result = await spawner(descriptor);
@@ -1,4 +1,5 @@
1
1
  import { d as defineHandler } from '../packem_shared/command-D3lB_4Az.mjs';
2
+ import { e as execArgsFor, d as detectPackageManager } from '../packem_shared/detect-package-manager-Cxo6Tpyx.mjs';
2
3
  import { defaultSpawner } from '../packem_shared/createRecordingSpawner-DxI3mebw.mjs';
3
4
 
4
5
  const withEnv = (args, env) => {
@@ -8,7 +9,7 @@ const withEnv = (args, env) => {
8
9
  return args;
9
10
  };
10
11
  const buildListArgs = (options) => {
11
- const args = withEnv(["exec", "wrangler", "deployments", "list"], options.env);
12
+ const args = withEnv(["deployments", "list"], options.env);
12
13
  if (options.json) {
13
14
  args.push("--json");
14
15
  }
@@ -20,7 +21,7 @@ const buildArgs = (options) => {
20
21
  if (options.versionId === void 0) {
21
22
  return { error: "deployments inspect requires a version id. Usage: lunora deployments inspect <version-id>" };
22
23
  }
23
- return { args: withEnv(["exec", "wrangler", "versions", "view", options.versionId], options.env) };
24
+ return { args: withEnv(["versions", "view", options.versionId], options.env) };
24
25
  }
25
26
  case "list": {
26
27
  return { args: buildListArgs(options) };
@@ -32,7 +33,7 @@ const buildArgs = (options) => {
32
33
  if (!options.yes) {
33
34
  return { error: "deployments promote shifts 100% of live traffic. Re-run with --yes to confirm." };
34
35
  }
35
- const args = withEnv(["exec", "wrangler", "versions", "deploy", `${options.versionId}@100%`, "--yes"], options.env);
36
+ const args = withEnv(["versions", "deploy", `${options.versionId}@100%`, "--yes"], options.env);
36
37
  if (options.message !== void 0) {
37
38
  args.push("--message", options.message);
38
39
  }
@@ -42,7 +43,7 @@ const buildArgs = (options) => {
42
43
  if (!options.yes) {
43
44
  return { error: "deployments rollback changes the live version. Re-run with --yes to confirm." };
44
45
  }
45
- const args = withEnv(["exec", "wrangler", "rollback"], options.env);
46
+ const args = withEnv(["rollback"], options.env);
46
47
  if (options.versionId !== void 0) {
47
48
  args.push(options.versionId);
48
49
  }
@@ -63,7 +64,9 @@ const runDeploymentsCommand = async (options) => {
63
64
  options.logger.error(error ?? "deployments: nothing to run");
64
65
  return { code: 1, descriptor: void 0, error };
65
66
  }
66
- const descriptor = { args, command: "pnpm", cwd: options.cwd ?? process.cwd() };
67
+ const cwd = options.cwd ?? process.cwd();
68
+ const exec = execArgsFor(detectPackageManager(cwd), "wrangler", args);
69
+ const descriptor = { args: exec.args, command: exec.command, cwd };
67
70
  options.logger.info(`${descriptor.command} ${descriptor.args.join(" ")}`);
68
71
  const spawner = options.spawner ?? defaultSpawner;
69
72
  const result = await spawner(descriptor);
@@ -2,6 +2,7 @@ import { writeFileSync, existsSync, readFileSync } from 'node:fs';
2
2
  import { join } from 'node:path';
3
3
  import { DEV_VARS_FILE, DEV_VARS_KEY_PATTERN, generateSecretValue, DEV_VARS_EXAMPLE_FILE, parseDevVariableEntries, isPlaceholderValue, packageNamesFromBindings, inferLunoraBindings, requiredSecrets, isMintableSecretKey } from '@lunora/config';
4
4
  import { d as defineHandler } from '../packem_shared/command-D3lB_4Az.mjs';
5
+ import { d as detectPackageManager, e as execArgsFor } from '../packem_shared/detect-package-manager-Cxo6Tpyx.mjs';
5
6
  import { defaultSpawner } from '../packem_shared/createRecordingSpawner-DxI3mebw.mjs';
6
7
  import { l as listRemoteSecrets } from '../packem_shared/wrangler-secrets-P2_ZUR-k.mjs';
7
8
 
@@ -115,19 +116,22 @@ const runEnvPush = async (context) => {
115
116
  return { code: 0, descriptors: [] };
116
117
  }
117
118
  const spawner = options.spawner ?? defaultSpawner;
119
+ const cwd = options.cwd ?? process.cwd();
120
+ const manager = detectPackageManager(cwd);
118
121
  const descriptors = [];
119
122
  for (const entry of map.values()) {
120
- const args = ["exec", "wrangler", "secret", "put", entry.key];
123
+ const args = ["secret", "put", entry.key];
121
124
  if (options.prod) {
122
125
  args.push("--env", "production");
123
126
  }
124
127
  if (options.temporary) {
125
128
  args.push("--temporary");
126
129
  }
130
+ const exec = execArgsFor(manager, "wrangler", args);
127
131
  const descriptor = {
128
- args,
129
- command: "pnpm",
130
- cwd: options.cwd ?? process.cwd(),
132
+ args: exec.args,
133
+ command: exec.command,
134
+ cwd,
131
135
  // `wrangler secret put <name>` reads the value from stdin. We
132
136
  // pipe it through the spawner's `input` channel so the secret
133
137
  // never lands on the command line, in env, or in shell history.
@@ -1,12 +1,12 @@
1
1
  import { spawn } from 'node:child_process';
2
- import { detectAgentRules, resolveRemoteEnabled, readProjectRemotePreference, inferLunoraBindings, packageNamesFromBindings, ensureDevVarsExample, ensureDevVariables, isInteractive, DEV_VARS_FILE, DEV_VARS_EXAMPLE_FILE, fillDevSecrets, discoverContainerInfo, streamContainerLogs, claimAgentRulesHint, AGENT_RULES_HINT, materializeRemoteWranglerConfig, formatLunoraEvent } from '@lunora/config';
2
+ import { detectAgentRules, resolveRemoteEnabled, readProjectRemotePreference, detectFramework, inferLunoraBindings, packageNamesFromBindings, ensureDevVarsExample, ensureDevVariables, isInteractive, DEV_VARS_FILE, DEV_VARS_EXAMPLE_FILE, fillDevSecrets, discoverContainerInfo, streamContainerLogs, claimAgentRulesHint, AGENT_RULES_HINT, materializeRemoteWranglerConfig, formatLunoraEvent } from '@lunora/config';
3
3
  import { p as parseApiSpec } from '../packem_shared/api-spec-CtA6ilu4.mjs';
4
4
  import { existsSync, watch } from 'node:fs';
5
5
  import { join } from 'node:path';
6
6
  import { runCodegen } from '@lunora/codegen';
7
7
  import { r as renderCodegenFailure } from '../packem_shared/codegen-error-DJG-ghs_.mjs';
8
8
  import { d as defineHandler } from '../packem_shared/command-D3lB_4Az.mjs';
9
- import { d as detectPackageManager, e as execArgsFor } from '../packem_shared/detect-package-manager-DYp7n3mJ.mjs';
9
+ import { d as detectPackageManager, e as execArgsFor, r as runScriptCommand } from '../packem_shared/detect-package-manager-Cxo6Tpyx.mjs';
10
10
  import { createServer, request } from 'node:http';
11
11
  import { connect } from 'node:net';
12
12
  import { loadStudioAssets, studioAssetsStamp, renderStudioHtml, resolveAdminToken, SCHEMA_EDIT_ENDPOINT, POLICY_SCAFFOLD_ENDPOINT, SEED_ENDPOINT, serveJsonHandler, handleSchemaEditRequest, handlePolicyScaffoldRequest, handleSeedRequest } from '@lunora/config/studio-host';
@@ -279,10 +279,13 @@ const planDevCommand = (options) => {
279
279
  const cwd = options.cwd ?? process.cwd();
280
280
  const workerPort = options.workerPort ?? DEFAULT_WORKER_PORT;
281
281
  const manager = detectPackageManager(cwd);
282
+ const detection = detectFramework(cwd);
283
+ const frameworkHint = detection.framework === "none" ? void 0 : `this project uses ${detection.framework} — the worker runs inside Vite there. run \`${runScriptCommand(manager, "dev")}\` for the full app (frontend + HMR); \`lunora dev\` starts only the worker.`;
282
284
  const remote = resolveRemotePlan(options, cwd);
283
285
  const exec = execArgsFor(manager, "wrangler", ["dev", "--port", String(workerPort), "--var", "WORKER_ENV:development", ...remote.args]);
284
286
  return {
285
287
  codegenEnabled: options.codegen !== false,
288
+ frameworkHint,
286
289
  remote: remote.plan,
287
290
  studioEnabled: options.studio !== false,
288
291
  studioPort: options.port ?? DEFAULT_STUDIO_PORT,
@@ -476,6 +479,9 @@ const runDevCommand = async (options) => {
476
479
  logger.warn(`studio server failed to start (${error instanceof Error ? error.message : String(error)}) — continuing without it`);
477
480
  }
478
481
  }
482
+ if (plan.frameworkHint !== void 0) {
483
+ logger.warn(plan.frameworkHint);
484
+ }
479
485
  const worker = (options.startWorker ?? defaultWorkerSpawner)(plan.wrangler, logger);
480
486
  try {
481
487
  handles.containerLogs = startContainerLogStreaming(cwd, logger);
@@ -7,6 +7,7 @@ import { Project } from 'ts-morph';
7
7
  import { p as parseApiSpec } from '../packem_shared/api-spec-CtA6ilu4.mjs';
8
8
  import { r as readWranglerName } from '../packem_shared/wrangler-name-cy4yhm9j.mjs';
9
9
  import { d as defineHandler } from '../packem_shared/command-D3lB_4Az.mjs';
10
+ import { e as execArgsFor, d as detectPackageManager } from '../packem_shared/detect-package-manager-Cxo6Tpyx.mjs';
10
11
  import { a as isRailpackAvailable, i as isDockerAvailable } from '../packem_shared/docker-hMQ97KSQ.mjs';
11
12
  import { v as validateOutputFormat, i as isJsonFormat, p as printJson, l as loggerForFormat } from '../packem_shared/output-format-wUvAN6AL.mjs';
12
13
  import { containerBuildTag } from '@lunora/container';
@@ -80,7 +81,8 @@ const buildRailpackImages = async (options) => {
80
81
  for (const target of options.targets) {
81
82
  const tag = containerBuildTag(target.exportName);
82
83
  const build = { args: ["build", target.buildDir, "--name", tag], command: "railpack", cwd: options.cwd };
83
- const push = { args: ["exec", "wrangler", "containers", "push", tag], command: "pnpm", cwd: options.cwd };
84
+ const pushExec = execArgsFor(detectPackageManager(options.cwd), "wrangler", ["containers", "push", tag]);
85
+ const push = { args: pushExec.args, command: pushExec.command, cwd: options.cwd };
84
86
  options.logger.info(`railpack: building "${target.exportName}" → ${tag} from ${target.buildDir}`);
85
87
  const buildResult = await spawner(build);
86
88
  if (buildResult.code !== 0) {
@@ -233,16 +235,18 @@ const resolveRequiredSecretKeys = async (cwd) => {
233
235
  const pushMintableSecrets = async (cwd, options, keys) => {
234
236
  const { logger } = options;
235
237
  const spawner = options.spawner ?? defaultSpawner;
238
+ const manager = detectPackageManager(cwd);
236
239
  const environmentFlag = options.env === void 0 ? "" : ` --env ${options.env}`;
237
240
  for (const key of keys) {
238
- const args = ["exec", "wrangler", "secret", "put", key];
241
+ const args = ["secret", "put", key];
239
242
  if (options.env !== void 0) {
240
243
  args.push("--env", options.env);
241
244
  }
242
245
  if (options.temporary === true) {
243
246
  args.push("--temporary");
244
247
  }
245
- const pushResult = await spawner({ args, command: "pnpm", cwd, input: generateSecretValue() });
248
+ const exec = execArgsFor(manager, "wrangler", args);
249
+ const pushResult = await spawner({ args: exec.args, command: exec.command, cwd, input: generateSecretValue() });
246
250
  if (pushResult.code !== 0) {
247
251
  logger.error(
248
252
  `failed to push secret ${key} (exit ${String(pushResult.code)}); set it manually with \`wrangler secret put ${key}${environmentFlag}\`.`
@@ -436,7 +440,7 @@ const runPreDeployGates = async (cwd, options) => {
436
440
  return buildContainerImages(cwd, options);
437
441
  };
438
442
  const buildWranglerDeployArgs = (cwd, options) => {
439
- const args = options.preview ? ["exec", "wrangler", "versions", "upload"] : ["exec", "wrangler", "deploy"];
443
+ const args = options.preview ? ["versions", "upload"] : ["deploy"];
440
444
  const composedEntry = resolveComposedWorkerEntry(cwd);
441
445
  if (composedEntry !== void 0) {
442
446
  args.push(composedEntry);
@@ -524,10 +528,11 @@ const executeDeploy = async (options) => {
524
528
  return { code: 1, descriptor: void 0, error: secretAbort, validation };
525
529
  }
526
530
  const shouldAutoLink = !isJsonFormat(options.format) && options.dryRun !== true && options.preview !== true && readLinkedProject(cwd) === void 0;
531
+ const exec = execArgsFor(detectPackageManager(cwd), "wrangler", buildWranglerDeployArgs(cwd, options));
527
532
  const descriptor = {
528
- args: buildWranglerDeployArgs(cwd, options),
533
+ args: exec.args,
529
534
  captureStdout: shouldAutoLink,
530
- command: "pnpm",
535
+ command: exec.command,
531
536
  cwd,
532
537
  // In `--format json` mode stdout is reserved for the single JSON document,
533
538
  // so route wrangler's progress + deployed-URL output to stderr instead.
@@ -7,7 +7,7 @@ import { downloadTemplate } from 'giget';
7
7
  import { modify, applyEdits } from 'jsonc-parser';
8
8
  import { join, dirname } from 'node:path';
9
9
  import { d as defineHandler } from '../packem_shared/command-D3lB_4Az.mjs';
10
- import { a as detectInstalledManagers, i as installArgsFor } from '../packem_shared/detect-package-manager-DYp7n3mJ.mjs';
10
+ import { d as detectPackageManager, a as detectInstalledManagers, i as installArgsFor, r as runScriptCommand } from '../packem_shared/detect-package-manager-Cxo6Tpyx.mjs';
11
11
  import MagicString from 'magic-string';
12
12
  import { Project, SyntaxKind } from 'ts-morph';
13
13
  import { P as PromptCancelledError } from '../packem_shared/prompt-cancelled-APzX1Im-.mjs';
@@ -1880,14 +1880,9 @@ const logScaffoldSuccess = (logger, written, target) => {
1880
1880
  }
1881
1881
  logger.success(`scaffolded ${String(written.length)} files into ${target}`);
1882
1882
  };
1883
- const runScriptCommand = (manager, script) => {
1884
- if (manager === "npm") {
1885
- return `npm run ${script}`;
1886
- }
1887
- if (manager === "bun") {
1888
- return `bun run ${script}`;
1889
- }
1890
- return `${manager} ${script}`;
1883
+ const installCommand = (manager, packages) => {
1884
+ const verb = manager === "npm" ? "install" : "add";
1885
+ return `${manager} ${verb} ${packages.join(" ")}`;
1891
1886
  };
1892
1887
  const isInsideMonorepo = (startDirectory) => {
1893
1888
  let directory = resolve(startDirectory);
@@ -2203,12 +2198,12 @@ const scaffoldLunoraDirectory = (cwd, logger) => {
2203
2198
  }
2204
2199
  return written;
2205
2200
  };
2206
- const printFrameworkNextSteps = (detection, logger) => {
2201
+ const printFrameworkNextSteps = (detection, manager, logger) => {
2207
2202
  const { adapter, class: frameworkClass, framework } = detection;
2208
2203
  logger.info("");
2209
2204
  logger.info(`detected framework: ${framework} (class ${frameworkClass})`);
2210
2205
  logger.info("next steps:");
2211
- logger.info(` 1. install the adapter: pnpm add ${adapter} @lunora/client @lunora/runtime @lunora/server`);
2206
+ logger.info(` 1. install the adapter: ${installCommand(manager, [adapter, "@lunora/client", "@lunora/runtime", "@lunora/server"])}`);
2212
2207
  logger.info(" 2. run codegen: lunora codegen");
2213
2208
  if (frameworkClass === "A") {
2214
2209
  logger.info(" 3. compose one worker: wrap your worker entry with");
@@ -2254,7 +2249,7 @@ const runInPlaceInit = (cwd, logger) => {
2254
2249
  return viteResult;
2255
2250
  }
2256
2251
  const scaffolded = scaffoldLunoraDirectory(cwd, logger);
2257
- printFrameworkNextSteps(detection, logger);
2252
+ printFrameworkNextSteps(detection, detectPackageManager(cwd), logger);
2258
2253
  return { code: 0, files: [...viteResult.files, ...scaffolded], target: cwd };
2259
2254
  };
2260
2255
  const offerIsInteractive = (options) => options.yes !== true && (options.prompt !== void 0 || (options.interactive ?? isInteractive()));
@@ -57,5 +57,14 @@ const execArgsFor = (manager, command, args) => {
57
57
  }
58
58
  return { args: ["exec", command, ...args], command: "pnpm" };
59
59
  };
60
+ const runScriptCommand = (manager, script) => {
61
+ if (manager === "npm") {
62
+ return `npm run ${script}`;
63
+ }
64
+ if (manager === "bun") {
65
+ return `bun run ${script}`;
66
+ }
67
+ return `${manager} ${script}`;
68
+ };
60
69
 
61
- export { detectInstalledManagers as a, detectPackageManager as d, execArgsFor as e, installArgsFor as i };
70
+ export { detectInstalledManagers as a, detectPackageManager as d, execArgsFor as e, installArgsFor as i, runScriptCommand as r };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lunora/cli",
3
- "version": "1.0.0-alpha.53",
3
+ "version": "1.0.0-alpha.55",
4
4
  "description": "The Lunora CLI: init, dev, deploy, codegen, run, reset, and migrate commands",
5
5
  "keywords": [
6
6
  "agent-skills",
@@ -52,11 +52,11 @@
52
52
  },
53
53
  "dependencies": {
54
54
  "@bomb.sh/tab": "0.0.17",
55
- "@lunora/codegen": "1.0.0-alpha.26",
56
- "@lunora/config": "1.0.0-alpha.41",
55
+ "@lunora/codegen": "1.0.0-alpha.27",
56
+ "@lunora/config": "1.0.0-alpha.43",
57
57
  "@lunora/container": "1.0.0-alpha.5",
58
- "@lunora/d1": "1.0.0-alpha.19",
59
- "@lunora/seed": "1.0.0-alpha.12",
58
+ "@lunora/d1": "1.0.0-alpha.20",
59
+ "@lunora/seed": "1.0.0-alpha.13",
60
60
  "@visulima/cerebro": "3.0.0-alpha.32",
61
61
  "@visulima/error": "6.0.0-alpha.34",
62
62
  "@visulima/fs": "5.0.0-alpha.32",