@lumerahq/cli 0.19.3-dev.0 → 0.19.4

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 (44) hide show
  1. package/README.md +5 -3
  2. package/dist/chunk-5T22627H.js +289 -0
  3. package/dist/chunk-H357NP7T.js +77 -0
  4. package/dist/{chunk-AUYOTENF.js → chunk-HU7RYLUF.js} +1 -1
  5. package/dist/{chunk-53NOF33P.js → chunk-SU26C4GL.js} +9 -49
  6. package/dist/{chunk-GKI2HQJC.js → chunk-UH5X43VV.js} +30 -3
  7. package/dist/{deps-ULTIIDYK.js → deps-GCOH3TXL.js} +4 -2
  8. package/dist/{dev-5JMHMS4U.js → dev-JLSTLIMZ.js} +14 -2
  9. package/dist/index.js +14 -14
  10. package/dist/{init-37XOMJLU.js → init-CBZAIERZ.js} +54 -24
  11. package/dist/{register-JJUMS4FI.js → register-N2LF3CCK.js} +1 -1
  12. package/dist/{resources-4IUZYKGX.js → resources-RHF2MDF7.js} +237 -159
  13. package/dist/{run-5ZOSPBGO.js → run-XJLB4AFD.js} +1 -1
  14. package/dist/{skills-TNJHMV4F.js → skills-REOKLNEF.js} +1 -1
  15. package/dist/{templates-M3RDNDDY.js → templates-LNUOTNLN.js} +2 -3
  16. package/package.json +1 -1
  17. package/templates/default/.agents/skills/.gitkeep +0 -0
  18. package/templates/default/AGENTS.md +151 -0
  19. package/templates/default/README.md +18 -0
  20. package/templates/default/_gitignore +14 -0
  21. package/templates/default/architecture.md +29 -0
  22. package/templates/default/biome.json +38 -0
  23. package/templates/default/components.json +21 -0
  24. package/templates/default/icon.svg +29 -0
  25. package/templates/default/index.html +16 -0
  26. package/templates/default/package.json +53 -0
  27. package/templates/default/platform/automations/.gitkeep +0 -0
  28. package/templates/default/platform/collections/.gitkeep +0 -0
  29. package/templates/default/platform/hooks/.gitkeep +0 -0
  30. package/templates/default/pyproject.toml +14 -0
  31. package/templates/default/scripts/.gitkeep +0 -0
  32. package/templates/default/src/components/layout.tsx +11 -0
  33. package/templates/default/src/lib/auth.ts +9 -0
  34. package/templates/default/src/lib/queries.ts +17 -0
  35. package/templates/default/src/lib/utils.ts +6 -0
  36. package/templates/default/src/main.tsx +130 -0
  37. package/templates/default/src/routes/__root.tsx +10 -0
  38. package/templates/default/src/routes/index.tsx +87 -0
  39. package/templates/default/src/styles.css +128 -0
  40. package/templates/default/template.json +7 -0
  41. package/templates/default/tsconfig.json +22 -0
  42. package/templates/default/vite.config.ts +28 -0
  43. package/dist/chunk-OQW5E7UT.js +0 -159
  44. package/dist/chunk-XDTWVFPE.js +0 -120
@@ -1,23 +1,23 @@
1
1
  import {
2
2
  installAllSkills,
3
3
  syncClaudeMd
4
- } from "./chunk-AUYOTENF.js";
4
+ } from "./chunk-HU7RYLUF.js";
5
5
  import {
6
6
  spinner
7
7
  } from "./chunk-BHYDYR75.js";
8
8
  import {
9
9
  createApiClient
10
- } from "./chunk-GKI2HQJC.js";
10
+ } from "./chunk-UH5X43VV.js";
11
11
  import {
12
12
  getToken,
13
13
  init_auth,
14
14
  setProjectId
15
15
  } from "./chunk-ZH3NVYEQ.js";
16
+ import "./chunk-FJFIWC7G.js";
16
17
  import {
17
18
  listAllTemplates,
18
19
  resolveTemplate
19
- } from "./chunk-OQW5E7UT.js";
20
- import "./chunk-FJFIWC7G.js";
20
+ } from "./chunk-H357NP7T.js";
21
21
  import "./chunk-PNKVD2UK.js";
22
22
 
23
23
  // src/commands/init.ts
@@ -25,7 +25,7 @@ init_auth();
25
25
  import pc from "picocolors";
26
26
  import prompts from "prompts";
27
27
  import { execSync } from "child_process";
28
- import { existsSync, mkdirSync, readdirSync, readFileSync, writeFileSync, rmSync } from "fs";
28
+ import { existsSync, mkdirSync, readdirSync, readFileSync, writeFileSync, rmSync, readlinkSync, symlinkSync } from "fs";
29
29
  import { join, resolve } from "path";
30
30
  function toTitleCase(str) {
31
31
  return str.split(/[-_]/).map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join(" ");
@@ -40,6 +40,7 @@ function processTemplate(content, replacements) {
40
40
  return result;
41
41
  }
42
42
  var TEMPLATE_EXCLUDE = /* @__PURE__ */ new Set(["template.json"]);
43
+ var TEMPLATE_RENAMES = /* @__PURE__ */ new Map([["_gitignore", ".gitignore"]]);
43
44
  function copyDir(src, dest, replacements, isRoot = true) {
44
45
  if (!existsSync(dest)) {
45
46
  mkdirSync(dest, { recursive: true });
@@ -47,8 +48,16 @@ function copyDir(src, dest, replacements, isRoot = true) {
47
48
  for (const entry of readdirSync(src, { withFileTypes: true })) {
48
49
  if (isRoot && TEMPLATE_EXCLUDE.has(entry.name)) continue;
49
50
  const srcPath = join(src, entry.name);
50
- const destPath = join(dest, entry.name);
51
- if (entry.isDirectory()) {
51
+ const destName = TEMPLATE_RENAMES.get(entry.name) ?? entry.name;
52
+ const destPath = join(dest, destName);
53
+ if (entry.isSymbolicLink()) {
54
+ try {
55
+ symlinkSync(readlinkSync(srcPath), destPath);
56
+ } catch {
57
+ const content = readFileSync(srcPath, "utf-8");
58
+ writeFileSync(destPath, processTemplate(content, replacements));
59
+ }
60
+ } else if (entry.isDirectory()) {
52
61
  copyDir(srcPath, destPath, replacements, false);
53
62
  } else {
54
63
  const content = readFileSync(srcPath, "utf-8");
@@ -57,6 +66,16 @@ function copyDir(src, dest, replacements, isRoot = true) {
57
66
  }
58
67
  }
59
68
  }
69
+ function ensureClaudeInstructionsLink(projectRoot) {
70
+ const agentsMdPath = join(projectRoot, "AGENTS.md");
71
+ const claudeMdPath = join(projectRoot, "CLAUDE.md");
72
+ if (!existsSync(agentsMdPath) || existsSync(claudeMdPath)) return;
73
+ try {
74
+ symlinkSync("AGENTS.md", claudeMdPath);
75
+ } catch {
76
+ writeFileSync(claudeMdPath, readFileSync(agentsMdPath, "utf-8"));
77
+ }
78
+ }
60
79
  function isGitInstalled() {
61
80
  try {
62
81
  execSync("git --version", { stdio: "ignore" });
@@ -193,9 +212,9 @@ ${pc.dim("Options:")}
193
212
 
194
213
  ${pc.dim("Examples:")}
195
214
  lumera init my-app # Interactive mode
196
- lumera init my-app -t invoice-processing # Use a specific template
215
+ lumera init my-app -t default # Use a specific template
197
216
  lumera init my-app -y # Non-interactive (default template)
198
- lumera init my-app -t invoice-processing -y -o # Full non-interactive + open editor
217
+ lumera init my-app -t default -y -o # Full non-interactive + open editor
199
218
  `);
200
219
  }
201
220
  async function init(args) {
@@ -218,7 +237,7 @@ async function init(args) {
218
237
  let templateName = opts.template;
219
238
  if (!templateName && !nonInteractive) {
220
239
  try {
221
- const stop = spinner("Fetching templates...");
240
+ const stop = spinner("Loading templates...");
222
241
  const available = await listAllTemplates();
223
242
  stop();
224
243
  if (available.length > 1) {
@@ -268,19 +287,24 @@ async function init(args) {
268
287
  }
269
288
  projectName = response.projectName;
270
289
  }
271
- if (!/^[a-z0-9-]+$/.test(projectName)) {
290
+ if (!projectName) {
291
+ console.log(pc.red(" Error: Project name is required"));
292
+ process.exit(1);
293
+ }
294
+ const finalProjectName = projectName;
295
+ if (!/^[a-z0-9-]+$/.test(finalProjectName)) {
272
296
  console.log(pc.red(" Error: Project name must use lowercase letters, numbers, and hyphens only"));
273
297
  process.exit(1);
274
298
  }
275
299
  if (!directory) {
276
300
  if (nonInteractive) {
277
- directory = projectName;
301
+ directory = finalProjectName;
278
302
  } else {
279
303
  const response = await prompts({
280
304
  type: "text",
281
305
  name: "directory",
282
306
  message: "Where should we create the project?",
283
- initial: projectName
307
+ initial: finalProjectName
284
308
  });
285
309
  if (!response.directory) {
286
310
  console.log(pc.red("Cancelled"));
@@ -289,14 +313,19 @@ async function init(args) {
289
313
  directory = response.directory;
290
314
  }
291
315
  }
292
- const projectTitle = toTitleCase(projectName);
293
- const targetDir = resolve(process.cwd(), directory);
316
+ if (!directory) {
317
+ console.log(pc.red(" Error: Directory is required"));
318
+ process.exit(1);
319
+ }
320
+ const finalDirectory = directory;
321
+ const projectTitle = toTitleCase(finalProjectName);
322
+ const targetDir = resolve(process.cwd(), finalDirectory);
294
323
  if (existsSync(targetDir)) {
295
324
  if (nonInteractive) {
296
325
  if (opts.force) {
297
326
  rmSync(targetDir, { recursive: true });
298
327
  } else {
299
- console.log(pc.red(` Error: Directory ${directory} already exists`));
328
+ console.log(pc.red(` Error: Directory ${finalDirectory} already exists`));
300
329
  console.log(pc.dim(" Use --force (-f) to overwrite"));
301
330
  process.exit(1);
302
331
  }
@@ -304,7 +333,7 @@ async function init(args) {
304
333
  const { overwrite } = await prompts({
305
334
  type: "confirm",
306
335
  name: "overwrite",
307
- message: `Directory ${directory} already exists. Overwrite?`,
336
+ message: `Directory ${finalDirectory} already exists. Overwrite?`,
308
337
  initial: false
309
338
  });
310
339
  if (!overwrite) {
@@ -317,9 +346,9 @@ async function init(args) {
317
346
  mkdirSync(targetDir, { recursive: true });
318
347
  console.log();
319
348
  if (templateName !== "default") {
320
- console.log(pc.dim(` Creating ${projectName} from template ${pc.cyan(templateName)}...`));
349
+ console.log(pc.dim(` Creating ${finalProjectName} from template ${pc.cyan(templateName)}...`));
321
350
  } else {
322
- console.log(pc.dim(` Creating ${projectName}...`));
351
+ console.log(pc.dim(` Creating ${finalProjectName}...`));
323
352
  }
324
353
  console.log();
325
354
  const templatePkgPath = join(templateDir, "package.json");
@@ -327,12 +356,13 @@ async function init(args) {
327
356
  const sourceName = templatePkg.name || "my-lumera-app";
328
357
  const sourceTitle = templatePkg.lumera?.name || toTitleCase(sourceName);
329
358
  const replacements = [
330
- ["{{projectName}}", projectName],
359
+ ["{{projectName}}", finalProjectName],
331
360
  ["{{projectTitle}}", projectTitle],
332
- [sourceName, projectName],
361
+ [sourceName, finalProjectName],
333
362
  [sourceTitle, projectTitle]
334
363
  ];
335
364
  copyDir(templateDir, targetDir, replacements);
365
+ ensureClaudeInstructionsLink(targetDir);
336
366
  function listFiles(dir, prefix = "") {
337
367
  for (const entry of readdirSync(dir, { withFileTypes: true })) {
338
368
  const relativePath = prefix + entry.name;
@@ -346,7 +376,7 @@ async function init(args) {
346
376
  listFiles(targetDir);
347
377
  if (isGitInstalled()) {
348
378
  const stopGit = spinner("Initializing git repository...");
349
- if (initGitRepo(targetDir, projectName)) {
379
+ if (initGitRepo(targetDir, finalProjectName)) {
350
380
  stopGit(pc.green("\u2713") + pc.dim(" Git repository initialized with initial commit"));
351
381
  } else {
352
382
  stopGit(pc.yellow("\u26A0") + pc.dim(" Failed to initialize git repository"));
@@ -408,7 +438,7 @@ async function init(args) {
408
438
  const api = createApiClient(token);
409
439
  const stopRegister = spinner("Registering project on Lumera...");
410
440
  try {
411
- const project = await api.registerProject(projectName);
441
+ const project = await api.registerProject(finalProjectName);
412
442
  setProjectId(targetDir, project.id);
413
443
  stopRegister(pc.green("\u2713") + pc.dim(` Project registered (${project.id})`));
414
444
  registered = true;
@@ -421,7 +451,7 @@ async function init(args) {
421
451
  console.log();
422
452
  console.log(pc.green(pc.bold(" Done!")), "Next steps:");
423
453
  console.log();
424
- console.log(pc.cyan(` cd ${directory}`));
454
+ console.log(pc.cyan(` cd ${finalDirectory}`));
425
455
  if (!opts.install) {
426
456
  console.log(pc.cyan(" pnpm install"));
427
457
  }
@@ -6,7 +6,7 @@ import {
6
6
  } from "./chunk-BHYDYR75.js";
7
7
  import {
8
8
  createApiClient
9
- } from "./chunk-GKI2HQJC.js";
9
+ } from "./chunk-UH5X43VV.js";
10
10
  import {
11
11
  findProjectRoot,
12
12
  getAppName,