create-mobile 0.1.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.
package/README.md ADDED
@@ -0,0 +1,76 @@
1
+ # create-mobile
2
+
3
+ > **The honest front door to a new mobile app.** `npm create mobile` doesn't silently
4
+ > pick a framework for you — it opens with Kotlin/Compose Multiplatform as the modern
5
+ > default, states the real trade-offs vs React Native and Flutter, and lets you choose.
6
+ > Continue, and it scaffolds a green-building Android + iOS app via
7
+ > [`create-cmp-cli`](https://www.npmjs.com/package/create-cmp-cli).
8
+
9
+ ```bash
10
+ npm create mobile@latest my-app
11
+ ```
12
+
13
+ ## Why this package exists — a fit check, not a redirect
14
+
15
+ "mobile" is framework-neutral, so a package under that name that quietly stamped one
16
+ stack would be a bait-and-switch. This one is built to earn the generic name. Launch it
17
+ and it opens with an honest positioning:
18
+
19
+ > Here's Compose Multiplatform as the modern default — one statically-typed codebase,
20
+ > real native Android + iOS UI, Google-backed, iOS stable since May 2025 — and here are
21
+ > the real trade-offs vs React Native/Flutter (bigger RN/Flutter ecosystems and hiring
22
+ > pools; a JS bridge or Dart's non-native render layer; CMP is the youngest of the three).
23
+ > **You choose.**
24
+
25
+ That's the same step-0 fit check the create-cmp Claude Code plugin's `cmp-new` skill runs,
26
+ brought to the command line. The generic name raises the honesty bar; this is how it's
27
+ cleared — you become the honest front door to mobile, not a redirect. The full sourced case
28
+ for choosing CMP (with its weaknesses named, not just its strengths) is
29
+ [docs/WHY-CMP.md](https://github.com/kvdm-co-pilot/create-cmp/blob/main/docs/WHY-CMP.md).
30
+
31
+ - **Interactive run:** you get the positioning **and a real prompt** —
32
+ `Continue with Compose Multiplatform? [Y/n]`. Decline and nothing is written; it points
33
+ you at `npm create expo` (React Native) or `flutter create` and exits cleanly.
34
+ - **Scripts / CI / agents (`--yes` or piped):** you've already chosen by how you invoked
35
+ it, so it prints the honest note and proceeds — no blocking prompt.
36
+ - **`--help` / `--version`:** pass straight through to the real CLI.
37
+
38
+ ## What you get if you continue
39
+
40
+ One command stamps a **frozen, CI-verified template** — deterministic output, never
41
+ LLM-freehanded project code:
42
+
43
+ - Android + iOS shells (XcodeGen + CocoaPods pre-wired), Clean Architecture with a worked
44
+ example feature, Koin DI, bottom navigation with insets solved.
45
+ - A **proven-green version set** (Kotlin/KSP/Compose/Room/AGP pinned to a combination that
46
+ actually builds together — including the iOS/KSP2 path).
47
+ - Optional features by flag: Firebase (GitLive) with auth, Room, Maestro on-device E2E, a
48
+ live UI inspector, a desktop hot-reload dev client. `--verify` builds the app before
49
+ reporting success; the CLI exits non-zero on failure.
50
+ - The **delivery harness** in every generated project: specs with stable clause ids, an
51
+ 8-gate verify lane (`node qa/verify.mjs`), evidence receipts bound to a content hash, a
52
+ device-free preview loop so coding agents see what they build, and CI that refuses "done"
53
+ without proof. See it working in the
54
+ [public showcase repo](https://github.com/kvdm-co-pilot/create-cmp-showcase) — including
55
+ [a PR the harness refuses](https://github.com/kvdm-co-pilot/create-cmp-showcase/pull/1).
56
+
57
+ ## About this package
58
+
59
+ An **official alias** for `create-cmp-cli`, published by the same maintainer so the
60
+ conventional `npm create mobile` invocation works. It adds exactly one thing of its own —
61
+ the honest fit check above — then delegates to the installed `create-cmp-cli`, forwarding
62
+ all arguments, stdio, and the exit code. After the choice, either name runs the same tool
63
+ with the same flags.
64
+
65
+ Fully non-interactive (scripts and AI agents):
66
+
67
+ ```bash
68
+ npx create-mobile my-app --name Acme --package com.acme.app --yes --verify
69
+ ```
70
+
71
+ ## Docs
72
+
73
+ - Repository, full README and issues: <https://github.com/kvdm-co-pilot/create-cmp>
74
+ - Why Compose Multiplatform (sourced, honest): [docs/WHY-CMP.md](https://github.com/kvdm-co-pilot/create-cmp/blob/main/docs/WHY-CMP.md)
75
+ - Every flag: [options.schema.json](https://github.com/kvdm-co-pilot/create-cmp/blob/main/options.schema.json) or `npx create-mobile --help`
76
+ - Usage guide (commands, skills, workflows): [docs/USAGE.md](https://github.com/kvdm-co-pilot/create-cmp/blob/main/docs/USAGE.md)
@@ -0,0 +1,111 @@
1
+ #!/usr/bin/env node
2
+ // create-mobile — the honest front door to a new mobile app.
3
+ //
4
+ // The other create-cmp aliases (create-kmp, create-compose-multiplatform) are pure
5
+ // pass-throughs: their name already names the framework, so they just re-exec
6
+ // create-cmp-cli. This one is deliberately NOT a silent pass-through. "mobile" is
7
+ // framework-neutral, so a package that quietly scaffolds Compose Multiplatform under
8
+ // that name would be a bait-and-switch. Instead it opens with an HONEST fit check —
9
+ // CMP as the modern default, the real trade-offs vs React Native / Flutter, and a
10
+ // genuine choice — and only then delegates to create-cmp-cli. The generic name
11
+ // raises the honesty bar; this is how it's earned (the CLI analogue of the cmp-new
12
+ // skill's step-0 fit check). Everything after the choice is create-cmp-cli, verbatim.
13
+
14
+ import { createRequire } from "node:module";
15
+ import { dirname, join } from "node:path";
16
+ import { spawnSync } from "node:child_process";
17
+ import { stdin, stdout } from "node:process";
18
+
19
+ const require = createRequire(import.meta.url);
20
+ const argv = process.argv.slice(2);
21
+
22
+ // --help / --version: pure info passthrough — no banner, no prompt.
23
+ const INFO = new Set(["--help", "-h", "--version", "-v"]);
24
+ const infoOnly = argv.some((a) => INFO.has(a));
25
+
26
+ function resolveCliPath() {
27
+ let pkgJsonPath;
28
+ try {
29
+ // package.json is always resolvable, even behind an "exports" map.
30
+ pkgJsonPath = require.resolve("create-cmp-cli/package.json");
31
+ } catch {
32
+ process.stderr.write(
33
+ "create-mobile: could not find its dependency create-cmp-cli.\n" +
34
+ "Your install may be broken — reinstall, or run the real CLI directly:\n\n" +
35
+ " npx create-cmp-cli@latest\n",
36
+ );
37
+ process.exit(1);
38
+ }
39
+ const pkg = require(pkgJsonPath);
40
+ const bin = pkg.bin;
41
+ const relBinPath = typeof bin === "string" ? bin : (bin["create-cmp"] ?? Object.values(bin)[0]);
42
+ if (!relBinPath) {
43
+ process.stderr.write(
44
+ "create-mobile: create-cmp-cli declares no bin entry.\n" +
45
+ "Run the real CLI directly instead: npx create-cmp-cli@latest\n",
46
+ );
47
+ process.exit(1);
48
+ }
49
+ return join(dirname(pkgJsonPath), relBinPath);
50
+ }
51
+
52
+ // Re-exec create-cmp-cli: block until it finishes, inherit stdio so interactive
53
+ // prompts keep working, propagate the exit code. Never returns (calls process.exit).
54
+ function delegate() {
55
+ const cliPath = resolveCliPath();
56
+ const result = spawnSync(process.execPath, [cliPath, ...argv], { stdio: "inherit" });
57
+ if (result.error) {
58
+ process.stderr.write(`create-mobile: failed to launch create-cmp-cli: ${result.error.message}\n`);
59
+ process.exit(1);
60
+ }
61
+ if (result.signal) process.kill(process.pid, result.signal);
62
+ process.exit(result.status ?? 1);
63
+ }
64
+
65
+ if (infoOnly) delegate(); // exits
66
+
67
+ // The honest positioning. To stderr so a piped stdout stays clean; both stream to
68
+ // the terminal in an interactive run, so the user always sees it.
69
+ const banner = [
70
+ "",
71
+ " create-mobile — the honest front door to a new mobile app.",
72
+ "",
73
+ " Recommended default: Kotlin / Compose Multiplatform (KMP)",
74
+ " - one statically-typed codebase, REAL native Android + iOS UI, no JS bridge",
75
+ " - Google-backed; Compose for iOS stable since May 2025",
76
+ "",
77
+ " The real trade-offs — know these before you choose:",
78
+ " - React Native / Expo: bigger ecosystem, more libraries and hiring pool,",
79
+ " but a JS<->native bridge and two languages at the edges",
80
+ " - Flutter: mature tooling and widgets, but Dart and a non-native render layer",
81
+ " - CMP is the youngest of the three: smaller community, newer iOS story",
82
+ "",
83
+ " Full sourced case: https://github.com/kvdm-co-pilot/create-cmp/blob/main/docs/WHY-CMP.md",
84
+ "",
85
+ ].join("\n");
86
+
87
+ process.stderr.write(banner + "\n");
88
+
89
+ // Flags-driven / --yes / no TTY => the caller already chose by how they invoked it
90
+ // (scripts, CI, an agent passing flags). Print the banner and proceed. A real
91
+ // interactive run gets a real choice.
92
+ const nonInteractive = argv.includes("--yes") || argv.includes("-y") || !stdin.isTTY || !stdout.isTTY;
93
+
94
+ if (nonInteractive) {
95
+ delegate(); // exits
96
+ }
97
+
98
+ const { createInterface } = await import("node:readline/promises");
99
+ const rl = createInterface({ input: stdin, output: stdout });
100
+ const answer = (await rl.question(" Continue with Compose Multiplatform? [Y/n] ")).trim().toLowerCase();
101
+ rl.close();
102
+
103
+ if (answer === "" || answer === "y" || answer === "yes") {
104
+ delegate(); // exits
105
+ }
106
+
107
+ process.stdout.write(
108
+ "\n No problem — nothing was written.\n" +
109
+ " Prefer another stack? React Native: npm create expo@latest · Flutter: flutter create my_app\n\n",
110
+ );
111
+ process.exit(0);
package/package.json ADDED
@@ -0,0 +1,51 @@
1
+ {
2
+ "name": "create-mobile",
3
+ "version": "0.1.0",
4
+ "description": "The honest front door to a new mobile app. `npm create mobile` recommends Kotlin/Compose Multiplatform as the modern default, states the real trade-offs vs React Native/Flutter, and lets you choose — then, if you continue, scaffolds a green-building Android + iOS app (one Kotlin codebase) with a machine-enforced verify lane and evidence receipts. Official alias for create-cmp-cli; not a redirect — a fit check first.",
5
+ "type": "module",
6
+ "bin": {
7
+ "create-mobile": "bin/create-mobile.mjs"
8
+ },
9
+ "engines": {
10
+ "node": ">=18"
11
+ },
12
+ "files": [
13
+ "bin"
14
+ ],
15
+ "keywords": [
16
+ "mobile app",
17
+ "create mobile app",
18
+ "new mobile app",
19
+ "cross-platform",
20
+ "app generator",
21
+ "react native alternative",
22
+ "flutter alternative",
23
+ "android",
24
+ "ios",
25
+ "compose-multiplatform",
26
+ "kotlin-multiplatform",
27
+ "kmp",
28
+ "cmp",
29
+ "scaffold",
30
+ "project-generator",
31
+ "claude-code",
32
+ "ai-agent"
33
+ ],
34
+ "license": "MIT",
35
+ "author": "Karel van der Merwe",
36
+ "homepage": "https://github.com/kvdm-co-pilot/create-cmp#readme",
37
+ "repository": {
38
+ "type": "git",
39
+ "url": "git+https://github.com/kvdm-co-pilot/create-cmp.git",
40
+ "directory": "packages/aliases/create-mobile"
41
+ },
42
+ "bugs": {
43
+ "url": "https://github.com/kvdm-co-pilot/create-cmp/issues"
44
+ },
45
+ "publishConfig": {
46
+ "access": "public"
47
+ },
48
+ "dependencies": {
49
+ "create-cmp-cli": ">=0.7.1"
50
+ }
51
+ }