create-jilatax 0.0.9 → 0.1.1

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/README.md CHANGED
@@ -17,8 +17,9 @@ cd my-app
17
17
  bun run run:android
18
18
  ```
19
19
 
20
- The creator asks for the application name, Android package ID, and whether to
21
- install dependencies. In non-interactive environments, pass the directory and
20
+ The creator derives the application name from the project directory, then asks
21
+ for the Android package ID and whether to install dependencies. Installation is
22
+ disabled by default. In non-interactive environments, pass the directory and
22
23
  options explicitly:
23
24
 
24
25
  ```bash
@@ -33,7 +34,8 @@ Generated projects include:
33
34
  - a Lynx and Rspeedy application;
34
35
  - `app.json` as the Jilatax application configuration;
35
36
  - an Android Gradle project linked to `jilatax/android`;
36
- - `bun run run:android` for development on a connected device;
37
+ - `bun run run:android` for development on a connected device; the generated
38
+ APK is located at `android/app/build/outputs/apk/debug/app-debug.apk`;
37
39
  - `bun run create:aab` for a Play Store Android App Bundle.
38
40
 
39
41
  The creator only writes the project and can run `bun install`. Device, Gradle,
package/dist/bin.cjs CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  //#region src/bin.ts
3
- require("./cli-6qr3BMqu.cjs").runCreateCli().then((exitCode) => {
3
+ require("./cli-Bh9_Txyy.cjs").runCreateCli().then((exitCode) => {
4
4
  process.exitCode = exitCode;
5
5
  });
6
6
  //#endregion
package/dist/bin.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { n as runCreateCli } from "./cli-CrpTfN81.js";
2
+ import { n as runCreateCli } from "./cli-BqzdpCyn.js";
3
3
  //#region src/bin.ts
4
4
  runCreateCli().then((exitCode) => {
5
5
  process.exitCode = exitCode;
@@ -23,10 +23,11 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
23
23
  let _clack_prompts = require("@clack/prompts");
24
24
  _clack_prompts = __toESM(_clack_prompts, 1);
25
25
  let node_fs_promises = require("node:fs/promises");
26
- let node_process = require("node:process");
27
- let node_child_process = require("node:child_process");
26
+ let node_os = require("node:os");
28
27
  let node_path = require("node:path");
29
28
  node_path = __toESM(node_path, 1);
29
+ let node_process = require("node:process");
30
+ let node_child_process = require("node:child_process");
30
31
  let node_url = require("node:url");
31
32
  let jilatax = require("jilatax");
32
33
  //#region src/generator.ts
@@ -63,7 +64,7 @@ async function createProject(options) {
63
64
  throw error;
64
65
  }
65
66
  const shouldInstall = options.install === true;
66
- if (shouldInstall) await (options.installer ?? installWithBun)(projectDirectory);
67
+ if (shouldInstall) await (options.installer ?? ((directory) => installWithBun(directory, options.silentInstall === true)))(projectDirectory);
67
68
  return {
68
69
  displayName,
69
70
  installed: shouldInstall,
@@ -184,20 +185,20 @@ function createInitialConfig(displayName, projectName, packageId) {
184
185
  android: {
185
186
  adaptiveIcon: {
186
187
  backgroundColor: "#E8FFF2",
187
- foregroundImage: "./assets/icon.png"
188
+ foregroundImage: "./public/assets/icon.png"
188
189
  },
189
190
  package: packageId,
190
191
  predictiveBackGestureEnabled: false,
191
192
  versionCode: 1
192
193
  },
193
- icon: "./assets/icon.png",
194
+ icon: "./public/assets/icon.png",
194
195
  name: displayName,
195
196
  orientation: "portrait",
196
197
  scheme: schemeBase || "jilatax-app",
197
198
  slug,
198
199
  splash: {
199
200
  backgroundColor: "#041A17",
200
- image: "./assets/splash-icon.png",
201
+ image: "./public/assets/splash-icon.png",
201
202
  imageWidth: 96,
202
203
  resizeMode: "contain"
203
204
  },
@@ -218,12 +219,12 @@ async function assertTargetDoesNotExist(target) {
218
219
  function titleCase$1(value) {
219
220
  return value.split(/[-_.\s]+/u).filter(Boolean).map((part) => `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`).join(" ");
220
221
  }
221
- function installWithBun(projectDirectory) {
222
+ function installWithBun(projectDirectory, silent) {
222
223
  return new Promise((resolveInstall, rejectInstall) => {
223
224
  const child = (0, node_child_process.spawn)("bun", ["install"], {
224
225
  cwd: projectDirectory,
225
226
  env: process.env,
226
- stdio: "inherit",
227
+ stdio: silent ? "ignore" : "inherit",
227
228
  windowsHide: true
228
229
  });
229
230
  child.once("error", rejectInstall);
@@ -252,13 +253,25 @@ async function runCreateCli(args = process.argv.slice(2), services = {}) {
252
253
  log(await readCreatorVersion());
253
254
  return 0;
254
255
  }
255
- const options = services.interactive ?? (node_process.stdin.isTTY && node_process.stdout.isTTY) ? await promptForOptions(parsed) : nonInteractiveOptions(parsed);
256
- printResult(await (services.create ?? createProject)({
257
- displayName: options.displayName,
258
- install: options.install,
259
- packageId: options.packageId,
260
- targetDirectory: options.targetDirectory
261
- }), log);
256
+ const interactive = services.interactive ?? (node_process.stdin.isTTY && node_process.stdout.isTTY);
257
+ const options = interactive ? await promptForOptions(parsed) : nonInteractiveOptions(parsed);
258
+ const generate = services.create ?? createProject;
259
+ const progress = interactive && options.install ? startInstallProgress() : void 0;
260
+ let result;
261
+ try {
262
+ result = await generate({
263
+ displayName: options.displayName,
264
+ install: options.install,
265
+ packageId: options.packageId,
266
+ ...progress === void 0 ? {} : { silentInstall: true },
267
+ targetDirectory: options.targetDirectory
268
+ });
269
+ } catch (error) {
270
+ progress?.fail();
271
+ throw error;
272
+ }
273
+ progress?.succeed();
274
+ printResult(result, log, interactive);
262
275
  return 0;
263
276
  } catch (error) {
264
277
  if (error instanceof PromptCancelledError) return 0;
@@ -316,7 +329,7 @@ function parseArgs(args) {
316
329
  };
317
330
  }
318
331
  async function promptForOptions(options) {
319
- _clack_prompts.intro("Jilatax · Android-first Lynx application");
332
+ printWelcome(await readCreatorVersion());
320
333
  const targetDirectory = options.targetDirectory ?? unwrapPrompt(await _clack_prompts.text({
321
334
  message: "Where should the project be created?",
322
335
  placeholder: "./my-jilatax-app",
@@ -329,17 +342,7 @@ async function promptForOptions(options) {
329
342
  }
330
343
  }));
331
344
  const projectName = normalizeProjectNameFromDirectory(targetDirectory);
332
- const displayName = options.displayName ?? unwrapPrompt(await _clack_prompts.text({
333
- initialValue: titleCase(projectName),
334
- message: "Application name",
335
- validate(value) {
336
- try {
337
- normalizeDisplayName(value ?? "");
338
- } catch (error) {
339
- return validationMessage(error);
340
- }
341
- }
342
- }));
345
+ const displayName = options.displayName ?? titleCase(projectName);
343
346
  const packageId = options.packageId ?? unwrapPrompt(await _clack_prompts.text({
344
347
  initialValue: defaultPackageId(projectName),
345
348
  message: "Android application ID",
@@ -352,7 +355,7 @@ async function promptForOptions(options) {
352
355
  }
353
356
  }));
354
357
  const install = options.install ?? unwrapPrompt(await _clack_prompts.confirm({
355
- initialValue: true,
358
+ initialValue: false,
356
359
  message: "Install dependencies with Bun?"
357
360
  }));
358
361
  return {
@@ -398,16 +401,92 @@ function readInlineValue(argument, option) {
398
401
  function titleCase(value) {
399
402
  return value.split(/[-_.\s]+/u).filter(Boolean).map((part) => `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`).join(" ");
400
403
  }
401
- function printResult(result, log) {
402
- const installStep = result.installed ? "" : " bun install\n";
403
- log(`Created ${result.displayName} in ${result.projectDirectory}.
404
-
405
- Next steps:
406
- cd ${JSON.stringify(result.projectDirectory)}
407
- ${installStep} bun run run:android
408
-
409
- Release bundle:
410
- bun run create:aab`);
404
+ function printWelcome(version) {
405
+ const reset = "\x1B[0m";
406
+ const cyan = "\x1B[36m";
407
+ console.log(`${`${cyan}◢▀▀▀ ▀▀▀◣${reset}\n${cyan} ◉ ◉${reset}\n${cyan} ╲▽╱${reset}`} ${cyan}Jilatax:${reset}\n Welcome to ${` jilatax ${reset}`} ${cyan}v${version}${reset}!\n`);
408
+ }
409
+ function startInstallProgress() {
410
+ const reset = "\x1B[0m";
411
+ const cyan = "\x1B[36m";
412
+ const dim = "\x1B[2m";
413
+ const green = "\x1B[32m";
414
+ const frames = [
415
+ [
416
+ 45,
417
+ 105,
418
+ 44,
419
+ 46
420
+ ],
421
+ [
422
+ 105,
423
+ 44,
424
+ 46,
425
+ 45
426
+ ],
427
+ [
428
+ 44,
429
+ 46,
430
+ 45,
431
+ 105
432
+ ],
433
+ [
434
+ 46,
435
+ 45,
436
+ 105,
437
+ 44
438
+ ]
439
+ ];
440
+ let frameIndex = 0;
441
+ const renderBar = () => {
442
+ const colors = frames[frameIndex % frames.length] ?? frames[0];
443
+ frameIndex += 1;
444
+ return `${colors.map((color) => `\u001B[${color}m `).join("")}${reset}`;
445
+ };
446
+ const renderTitle = () => `${renderBar()} Project initializing...`;
447
+ node_process.stdout.write(`\u001B[?25l${renderTitle()}\n ${cyan}▸ Installing dependencies with Bun...${reset}\u001B[1A\r`);
448
+ const timer = setInterval(() => {
449
+ node_process.stdout.write(`\u001B[2K${renderTitle()}\r`);
450
+ }, 120);
451
+ const finish = (title, detail) => {
452
+ clearInterval(timer);
453
+ node_process.stdout.write(`\u001B[2K\r\u001B[1B\r\u001B[2K\u001B[1A\r${title}\n${detail}\n\u001B[?25h`);
454
+ };
455
+ return {
456
+ fail() {
457
+ finish(`${cyan}▲${reset} Project initialization failed.`, "");
458
+ },
459
+ succeed() {
460
+ finish(`${green}✓ Project initialized!${reset}`, ` ${dim}▪ Dependencies installed${reset}\n`);
461
+ }
462
+ };
463
+ }
464
+ function printResult(result, log, interactive) {
465
+ const message = [
466
+ "🛠️ Next steps:",
467
+ ` cd ${formatProjectDirectory(result.projectDirectory)}`,
468
+ ...result.installed ? [] : [" bun install"],
469
+ " bun run dev",
470
+ "",
471
+ "🤖 Android:",
472
+ " bun run run:android",
473
+ " bun run create:aab"
474
+ ].join("\n");
475
+ const farewell = `Good luck out there, ${result.projectName}! 🎉`;
476
+ if (interactive) {
477
+ _clack_prompts.note(message, "Result");
478
+ _clack_prompts.outro(farewell);
479
+ return;
480
+ }
481
+ log(`${message}\n\n${farewell}`);
482
+ }
483
+ function formatProjectDirectory(projectDirectory) {
484
+ const relativeDirectory = node_path.default.relative(process.cwd(), projectDirectory);
485
+ const cwdPath = relativeDirectory.length === 0 ? "." : relativeDirectory.startsWith("..") || node_path.default.isAbsolute(relativeDirectory) ? relativeDirectory : `.${node_path.default.sep}${relativeDirectory}`;
486
+ const homeRelative = node_path.default.relative((0, node_os.homedir)(), projectDirectory);
487
+ const homePath = homeRelative.length === 0 ? "~" : homeRelative.startsWith("..") || node_path.default.isAbsolute(homeRelative) ? void 0 : `~/${homeRelative.split(node_path.default.sep).join("/")}`;
488
+ const shortestPath = homePath !== void 0 && homePath.length < cwdPath.length ? homePath : cwdPath;
489
+ return /\s/u.test(shortestPath) ? JSON.stringify(shortestPath) : shortestPath;
411
490
  }
412
491
  async function readCreatorVersion() {
413
492
  const packageJson = JSON.parse(await (0, node_fs_promises.readFile)(new URL("../package.json", require("url").pathToFileURL(__filename).href), "utf8"));
@@ -1,8 +1,9 @@
1
1
  import * as prompts from "@clack/prompts";
2
2
  import { chmod, copyFile, lstat, mkdir, mkdtemp, readFile, readdir, rename, rm, writeFile } from "node:fs/promises";
3
+ import { homedir } from "node:os";
4
+ import path from "node:path";
3
5
  import { stdin, stdout } from "node:process";
4
6
  import { spawn } from "node:child_process";
5
- import path from "node:path";
6
7
  import { fileURLToPath } from "node:url";
7
8
  import { parseAppConfig, syncAndroidProjectConfig } from "jilatax";
8
9
  //#region src/generator.ts
@@ -39,7 +40,7 @@ async function createProject(options) {
39
40
  throw error;
40
41
  }
41
42
  const shouldInstall = options.install === true;
42
- if (shouldInstall) await (options.installer ?? installWithBun)(projectDirectory);
43
+ if (shouldInstall) await (options.installer ?? ((directory) => installWithBun(directory, options.silentInstall === true)))(projectDirectory);
43
44
  return {
44
45
  displayName,
45
46
  installed: shouldInstall,
@@ -160,20 +161,20 @@ function createInitialConfig(displayName, projectName, packageId) {
160
161
  android: {
161
162
  adaptiveIcon: {
162
163
  backgroundColor: "#E8FFF2",
163
- foregroundImage: "./assets/icon.png"
164
+ foregroundImage: "./public/assets/icon.png"
164
165
  },
165
166
  package: packageId,
166
167
  predictiveBackGestureEnabled: false,
167
168
  versionCode: 1
168
169
  },
169
- icon: "./assets/icon.png",
170
+ icon: "./public/assets/icon.png",
170
171
  name: displayName,
171
172
  orientation: "portrait",
172
173
  scheme: schemeBase || "jilatax-app",
173
174
  slug,
174
175
  splash: {
175
176
  backgroundColor: "#041A17",
176
- image: "./assets/splash-icon.png",
177
+ image: "./public/assets/splash-icon.png",
177
178
  imageWidth: 96,
178
179
  resizeMode: "contain"
179
180
  },
@@ -194,12 +195,12 @@ async function assertTargetDoesNotExist(target) {
194
195
  function titleCase$1(value) {
195
196
  return value.split(/[-_.\s]+/u).filter(Boolean).map((part) => `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`).join(" ");
196
197
  }
197
- function installWithBun(projectDirectory) {
198
+ function installWithBun(projectDirectory, silent) {
198
199
  return new Promise((resolveInstall, rejectInstall) => {
199
200
  const child = spawn("bun", ["install"], {
200
201
  cwd: projectDirectory,
201
202
  env: process.env,
202
- stdio: "inherit",
203
+ stdio: silent ? "ignore" : "inherit",
203
204
  windowsHide: true
204
205
  });
205
206
  child.once("error", rejectInstall);
@@ -228,13 +229,25 @@ async function runCreateCli(args = process.argv.slice(2), services = {}) {
228
229
  log(await readCreatorVersion());
229
230
  return 0;
230
231
  }
231
- const options = services.interactive ?? (stdin.isTTY && stdout.isTTY) ? await promptForOptions(parsed) : nonInteractiveOptions(parsed);
232
- printResult(await (services.create ?? createProject)({
233
- displayName: options.displayName,
234
- install: options.install,
235
- packageId: options.packageId,
236
- targetDirectory: options.targetDirectory
237
- }), log);
232
+ const interactive = services.interactive ?? (stdin.isTTY && stdout.isTTY);
233
+ const options = interactive ? await promptForOptions(parsed) : nonInteractiveOptions(parsed);
234
+ const generate = services.create ?? createProject;
235
+ const progress = interactive && options.install ? startInstallProgress() : void 0;
236
+ let result;
237
+ try {
238
+ result = await generate({
239
+ displayName: options.displayName,
240
+ install: options.install,
241
+ packageId: options.packageId,
242
+ ...progress === void 0 ? {} : { silentInstall: true },
243
+ targetDirectory: options.targetDirectory
244
+ });
245
+ } catch (error) {
246
+ progress?.fail();
247
+ throw error;
248
+ }
249
+ progress?.succeed();
250
+ printResult(result, log, interactive);
238
251
  return 0;
239
252
  } catch (error) {
240
253
  if (error instanceof PromptCancelledError) return 0;
@@ -292,7 +305,7 @@ function parseArgs(args) {
292
305
  };
293
306
  }
294
307
  async function promptForOptions(options) {
295
- prompts.intro("Jilatax · Android-first Lynx application");
308
+ printWelcome(await readCreatorVersion());
296
309
  const targetDirectory = options.targetDirectory ?? unwrapPrompt(await prompts.text({
297
310
  message: "Where should the project be created?",
298
311
  placeholder: "./my-jilatax-app",
@@ -305,17 +318,7 @@ async function promptForOptions(options) {
305
318
  }
306
319
  }));
307
320
  const projectName = normalizeProjectNameFromDirectory(targetDirectory);
308
- const displayName = options.displayName ?? unwrapPrompt(await prompts.text({
309
- initialValue: titleCase(projectName),
310
- message: "Application name",
311
- validate(value) {
312
- try {
313
- normalizeDisplayName(value ?? "");
314
- } catch (error) {
315
- return validationMessage(error);
316
- }
317
- }
318
- }));
321
+ const displayName = options.displayName ?? titleCase(projectName);
319
322
  const packageId = options.packageId ?? unwrapPrompt(await prompts.text({
320
323
  initialValue: defaultPackageId(projectName),
321
324
  message: "Android application ID",
@@ -328,7 +331,7 @@ async function promptForOptions(options) {
328
331
  }
329
332
  }));
330
333
  const install = options.install ?? unwrapPrompt(await prompts.confirm({
331
- initialValue: true,
334
+ initialValue: false,
332
335
  message: "Install dependencies with Bun?"
333
336
  }));
334
337
  return {
@@ -374,16 +377,92 @@ function readInlineValue(argument, option) {
374
377
  function titleCase(value) {
375
378
  return value.split(/[-_.\s]+/u).filter(Boolean).map((part) => `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`).join(" ");
376
379
  }
377
- function printResult(result, log) {
378
- const installStep = result.installed ? "" : " bun install\n";
379
- log(`Created ${result.displayName} in ${result.projectDirectory}.
380
-
381
- Next steps:
382
- cd ${JSON.stringify(result.projectDirectory)}
383
- ${installStep} bun run run:android
384
-
385
- Release bundle:
386
- bun run create:aab`);
380
+ function printWelcome(version) {
381
+ const reset = "\x1B[0m";
382
+ const cyan = "\x1B[36m";
383
+ console.log(`${`${cyan}◢▀▀▀ ▀▀▀◣${reset}\n${cyan} ◉ ◉${reset}\n${cyan} ╲▽╱${reset}`} ${cyan}Jilatax:${reset}\n Welcome to ${` jilatax ${reset}`} ${cyan}v${version}${reset}!\n`);
384
+ }
385
+ function startInstallProgress() {
386
+ const reset = "\x1B[0m";
387
+ const cyan = "\x1B[36m";
388
+ const dim = "\x1B[2m";
389
+ const green = "\x1B[32m";
390
+ const frames = [
391
+ [
392
+ 45,
393
+ 105,
394
+ 44,
395
+ 46
396
+ ],
397
+ [
398
+ 105,
399
+ 44,
400
+ 46,
401
+ 45
402
+ ],
403
+ [
404
+ 44,
405
+ 46,
406
+ 45,
407
+ 105
408
+ ],
409
+ [
410
+ 46,
411
+ 45,
412
+ 105,
413
+ 44
414
+ ]
415
+ ];
416
+ let frameIndex = 0;
417
+ const renderBar = () => {
418
+ const colors = frames[frameIndex % frames.length] ?? frames[0];
419
+ frameIndex += 1;
420
+ return `${colors.map((color) => `\u001B[${color}m `).join("")}${reset}`;
421
+ };
422
+ const renderTitle = () => `${renderBar()} Project initializing...`;
423
+ stdout.write(`\u001B[?25l${renderTitle()}\n ${cyan}▸ Installing dependencies with Bun...${reset}\u001B[1A\r`);
424
+ const timer = setInterval(() => {
425
+ stdout.write(`\u001B[2K${renderTitle()}\r`);
426
+ }, 120);
427
+ const finish = (title, detail) => {
428
+ clearInterval(timer);
429
+ stdout.write(`\u001B[2K\r\u001B[1B\r\u001B[2K\u001B[1A\r${title}\n${detail}\n\u001B[?25h`);
430
+ };
431
+ return {
432
+ fail() {
433
+ finish(`${cyan}▲${reset} Project initialization failed.`, "");
434
+ },
435
+ succeed() {
436
+ finish(`${green}✓ Project initialized!${reset}`, ` ${dim}▪ Dependencies installed${reset}\n`);
437
+ }
438
+ };
439
+ }
440
+ function printResult(result, log, interactive) {
441
+ const message = [
442
+ "🛠️ Next steps:",
443
+ ` cd ${formatProjectDirectory(result.projectDirectory)}`,
444
+ ...result.installed ? [] : [" bun install"],
445
+ " bun run dev",
446
+ "",
447
+ "🤖 Android:",
448
+ " bun run run:android",
449
+ " bun run create:aab"
450
+ ].join("\n");
451
+ const farewell = `Good luck out there, ${result.projectName}! 🎉`;
452
+ if (interactive) {
453
+ prompts.note(message, "Result");
454
+ prompts.outro(farewell);
455
+ return;
456
+ }
457
+ log(`${message}\n\n${farewell}`);
458
+ }
459
+ function formatProjectDirectory(projectDirectory) {
460
+ const relativeDirectory = path.relative(process.cwd(), projectDirectory);
461
+ const cwdPath = relativeDirectory.length === 0 ? "." : relativeDirectory.startsWith("..") || path.isAbsolute(relativeDirectory) ? relativeDirectory : `.${path.sep}${relativeDirectory}`;
462
+ const homeRelative = path.relative(homedir(), projectDirectory);
463
+ const homePath = homeRelative.length === 0 ? "~" : homeRelative.startsWith("..") || path.isAbsolute(homeRelative) ? void 0 : `~/${homeRelative.split(path.sep).join("/")}`;
464
+ const shortestPath = homePath !== void 0 && homePath.length < cwdPath.length ? homePath : cwdPath;
465
+ return /\s/u.test(shortestPath) ? JSON.stringify(shortestPath) : shortestPath;
387
466
  }
388
467
  async function readCreatorVersion() {
389
468
  const packageJson = JSON.parse(await readFile(new URL("../package.json", import.meta.url), "utf8"));
package/dist/index.cjs CHANGED
@@ -1,5 +1,5 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_cli = require("./cli-6qr3BMqu.cjs");
2
+ const require_cli = require("./cli-Bh9_Txyy.cjs");
3
3
  exports.createHelpText = require_cli.createHelpText;
4
4
  exports.createProject = require_cli.createProject;
5
5
  exports.defaultPackageId = require_cli.defaultPackageId;
package/dist/index.d.cts CHANGED
@@ -4,6 +4,7 @@ interface CreateProjectOptions {
4
4
  readonly install?: boolean;
5
5
  readonly installer?: ProjectInstaller;
6
6
  readonly packageId?: string;
7
+ readonly silentInstall?: boolean;
7
8
  readonly targetDirectory: string;
8
9
  }
9
10
  interface CreateProjectResult {
package/dist/index.d.ts CHANGED
@@ -4,6 +4,7 @@ interface CreateProjectOptions {
4
4
  readonly install?: boolean;
5
5
  readonly installer?: ProjectInstaller;
6
6
  readonly packageId?: string;
7
+ readonly silentInstall?: boolean;
7
8
  readonly targetDirectory: string;
8
9
  }
9
10
  interface CreateProjectResult {
package/dist/index.js CHANGED
@@ -1,2 +1,2 @@
1
- import { a as normalizeDisplayName, i as defaultPackageId, n as runCreateCli, o as normalizeProjectName, r as createProject, s as validatePackageId, t as createHelpText } from "./cli-CrpTfN81.js";
1
+ import { a as normalizeDisplayName, i as defaultPackageId, n as runCreateCli, o as normalizeProjectName, r as createProject, s as validatePackageId, t as createHelpText } from "./cli-BqzdpCyn.js";
2
2
  export { createHelpText, createProject, defaultPackageId, normalizeDisplayName, normalizeProjectName, runCreateCli, validatePackageId };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-jilatax",
3
- "version": "0.0.9",
3
+ "version": "0.1.1",
4
4
  "packageManager": "bun@1.3.4",
5
5
  "description": "Create an Android-first Jilatax application for Lynx and Rspeedy.",
6
6
  "type": "module",
@@ -2,20 +2,21 @@
2
2
 
3
3
  Android-first Lynx application created with Jilatax.
4
4
 
5
- ## Development
5
+ ## Development (QR)
6
6
 
7
7
  ```bash
8
- bun install
9
- bun run run:android
8
+ bun i
9
+ bun run dev
10
10
  ```
11
11
 
12
12
  The Android command starts Rspeedy, builds and installs the debug APK, verifies
13
- the ADB reverse tunnel, and launches the app once.
13
+ the ADB reverse tunnel, and launches the app once. The generated APK is located
14
+ at `android/app/build/outputs/apk/debug/app-debug.apk`.
14
15
 
15
- To run only the Lynx development server:
16
+ To run only the Lynx development APK (Real Mobile):
16
17
 
17
18
  ```bash
18
- bun run dev
19
+ bun run run:android
19
20
  ```
20
21
 
21
22
  When the build is ready, scan the printed QR code with the Lynx application on
@@ -33,6 +34,8 @@ Play Store release. Never commit signing credentials.
33
34
  Application metadata lives in `app.json`. Android is the only supported native
34
35
  platform in this phase.
35
36
 
36
- Default launcher and splash artwork lives in `assets/`. Update the image paths,
37
- background colors, or splash width in `app.json`; Jilatax synchronizes those
38
- resources before each Android build.
37
+ Default launcher and splash artwork lives in `public/assets/`. Additional local
38
+ fonts can be stored in `public/fonts/`; the included JilataX font is applied to
39
+ the `LYNX TO ANDROID` brand caption. Update the image paths, background colors,
40
+ or splash width in `app.json`; Jilatax synchronizes those resources before each
41
+ Android build.
@@ -1,4 +1,4 @@
1
- import jilataxIcon from '../../../assets/jilatax-icon.png';
1
+ import jilataxIcon from '../../../public/assets/jilatax-icon.png';
2
2
 
3
3
  interface BrandProps {
4
4
  compact?: boolean;
@@ -7,7 +7,7 @@ interface BrandProps {
7
7
  export function Brand({ compact = false }: BrandProps) {
8
8
  return (
9
9
  <view className={`brand${compact ? ' brand--compact' : ''}`}>
10
- <view className={`brand__icon-wrap${compact ? ' brand__icon-wrap--compact' : ''}`}>
10
+ <view className="brand__icon-wrap">
11
11
  <image className="brand__icon" mode="aspectFit" src={jilataxIcon} />
12
12
  </view>
13
13
  <view className="brand__copy">
@@ -1,3 +1,8 @@
1
+ @font-face {
2
+ font-family: JilataX;
3
+ src: url('../../public/fonts/JilataX.otf');
4
+ }
5
+
1
6
  :root {
2
7
  background-color: #f3f7f5;
3
8
  color: #10241d;
@@ -36,17 +41,11 @@
36
41
  .brand__icon-wrap {
37
42
  align-items: center;
38
43
  background-color: #e3eee9;
39
- border-radius: 18px;
44
+ border-radius: 15px;
40
45
  display: flex;
41
- height: 58px;
46
+ height: 48px;
42
47
  justify-content: center;
43
48
  overflow: hidden;
44
- width: 58px;
45
- }
46
-
47
- .brand__icon-wrap--compact {
48
- border-radius: 15px;
49
- height: 48px;
50
49
  width: 48px;
51
50
  }
52
51
 
@@ -71,8 +70,8 @@
71
70
 
72
71
  .brand__caption {
73
72
  color: #688078;
73
+ font-family: JilataX;
74
74
  font-size: 9px;
75
- font-weight: 700;
76
75
  letter-spacing: 1.5px;
77
76
  line-height: 14px;
78
77
  margin-top: 2px;
File without changes