kappmaker 1.0.1 → 1.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.
Files changed (44) hide show
  1. package/README.md +315 -41
  2. package/dist/cli.js +60 -0
  3. package/dist/cli.js.map +1 -1
  4. package/dist/commands/android-release-build.d.ts +7 -0
  5. package/dist/commands/android-release-build.js +51 -0
  6. package/dist/commands/android-release-build.js.map +1 -0
  7. package/dist/commands/create.js +47 -46
  8. package/dist/commands/create.js.map +1 -1
  9. package/dist/commands/generate-keystore.d.ts +7 -0
  10. package/dist/commands/generate-keystore.js +14 -0
  11. package/dist/commands/generate-keystore.js.map +1 -0
  12. package/dist/commands/publish.d.ts +10 -0
  13. package/dist/commands/publish.js +38 -0
  14. package/dist/commands/publish.js.map +1 -0
  15. package/dist/commands/refactor.d.ts +9 -0
  16. package/dist/commands/refactor.js +9 -0
  17. package/dist/commands/refactor.js.map +1 -0
  18. package/dist/commands/update-version.d.ts +5 -0
  19. package/dist/commands/update-version.js +21 -0
  20. package/dist/commands/update-version.js.map +1 -0
  21. package/dist/services/fastlane.service.js +20 -8
  22. package/dist/services/fastlane.service.js.map +1 -1
  23. package/dist/services/firebase.service.d.ts +1 -1
  24. package/dist/services/firebase.service.js +9 -9
  25. package/dist/services/firebase.service.js.map +1 -1
  26. package/dist/services/gradle.service.d.ts +0 -3
  27. package/dist/services/gradle.service.js +0 -24
  28. package/dist/services/gradle.service.js.map +1 -1
  29. package/dist/services/keystore.service.d.ts +6 -0
  30. package/dist/services/keystore.service.js +44 -0
  31. package/dist/services/keystore.service.js.map +1 -0
  32. package/dist/services/publish.service.d.ts +10 -0
  33. package/dist/services/publish.service.js +59 -0
  34. package/dist/services/publish.service.js.map +1 -0
  35. package/dist/services/refactor.service.d.ts +3 -0
  36. package/dist/services/refactor.service.js +192 -0
  37. package/dist/services/refactor.service.js.map +1 -0
  38. package/dist/services/version.service.d.ts +10 -0
  39. package/dist/services/version.service.js +75 -0
  40. package/dist/services/version.service.js.map +1 -0
  41. package/dist/types/index.d.ts +1 -0
  42. package/dist/utils/config.js +1 -0
  43. package/dist/utils/config.js.map +1 -1
  44. package/package.json +1 -1
package/README.md CHANGED
@@ -1,32 +1,112 @@
1
1
  # KAppMaker CLI
2
2
 
3
- CLI tool that automates the entire mobile app launch process — from project setup to store-ready builds. One command takes you from zero to a configured Firebase project, App Store listing, subscription products, and a signed release build.
3
+ CLI tool that automates the entire mobile app launch process — from project scaffolding to store-ready builds.
4
4
 
5
- By default it uses the [KAppMaker](https://kappmaker.com) boilerplate (Kotlin Multiplatform), but you can bring your own template repository via `--template-repo` or `kappmaker config set templateRepo <your-repo-url>`.
5
+ A single `kappmaker create` command can:
6
+ - Clone a template repository and set up a new project
7
+ - Create a Firebase project, register Android + iOS apps, enable authentication, and download SDK configs
8
+ - Generate an AI-powered app logo with automatic background removal
9
+ - Create an App Store Connect listing with metadata, categories, age rating, subscriptions, privacy declarations, and review contact info
10
+ - Set up Adapty subscription products, paywalls, and placements for both iOS and Android
11
+ - Refactor Gradle package names and application IDs
12
+ - Set up the build environment (Android SDK, CocoaPods)
13
+ - Produce a signed Android release build (AAB) via Fastlane, ready to upload to Google Play
6
14
 
7
- ## Features
15
+ On top of that, standalone commands let you generate marketing screenshots from a text description, translate screenshots to 48+ locales in parallel, remove image backgrounds, enhance image quality, and split grid images — all powered by AI.
8
16
 
9
- ### Works with any project
17
+ By default it uses the [KAppMaker](https://kappmaker.com) boilerplate (Kotlin Multiplatform), but you can bring your own template repository via `--template-repo` or `kappmaker config set templateRepo <your-repo-url>`. Boilerplate-specific steps (Gradle refactor, Fastlane build, CocoaPods) are automatically detected and skipped with a warning when using a custom template.
10
18
 
11
- These commands are standalone and don't depend on any specific boilerplate:
19
+ ## Installation
12
20
 
13
- - **AI logo generation** — Generate logo variations with fal.ai, pick your favorite, auto-remove background
14
- - **AI screenshot generation** — Generate marketing screenshots from a text description (8 style presets)
15
- - **Screenshot translation** — Translate app screenshots to 48+ locales in parallel
16
- - **App Store Connect setup** — Register bundle ID, create app, set metadata, categories, age rating, subscriptions, privacy, and review info
17
- - **Adapty subscription setup** — Create products, paywalls, and placements for iOS and Android
18
- - **Image tools** — Split grids, remove backgrounds, enhance quality
21
+ ```bash
22
+ npm install -g kappmaker
23
+ ```
19
24
 
20
- ### KAppMaker boilerplate-specific
25
+ Then use it anywhere:
21
26
 
22
- The `create` command runs the full end-to-end setup. Some steps assume the [KAppMaker](https://kappmaker.com) project structure and will be skipped with a warning if you use a custom template:
27
+ ```bash
28
+ kappmaker create <AppName>
29
+ ```
23
30
 
24
- - **Gradle refactor** — Renames package name and app ID using a custom Gradle task (`refactorPackage`) built into the KAppMaker template
25
- - **Firebase SDK config placement** — Downloads `google-services.json` and `GoogleService-Info.plist` to KAppMaker-specific paths (`MobileApp/composeApp/` and `MobileApp/iosApp/iosApp/`)
26
- - **Build environment** — Creates `local.properties` and runs CocoaPods in the `MobileApp/` directory
27
- - **Android release build** — Runs Fastlane `first_time_build` lane defined in the KAppMaker template
28
- - **Git remotes** — Renames origin to upstream (designed for the "fork from template" workflow)
29
- - **Screenshot translation default path** — Defaults to `MobileApp/distribution/ios/appstore_metadata/screenshots/en-US`
31
+ <details>
32
+ <summary>Development setup</summary>
33
+
34
+ ```bash
35
+ npm install
36
+ npx tsx src/index.ts create <AppName>
37
+ ```
38
+
39
+ </details>
40
+
41
+ ## Configuration
42
+
43
+ Run interactive setup to configure API keys and preferences:
44
+
45
+ ```bash
46
+ kappmaker config init
47
+ ```
48
+
49
+ Or set keys individually:
50
+
51
+ ```bash
52
+ kappmaker config set falApiKey <your-key> # Required for AI features (logo, screenshots, etc.)
53
+ kappmaker config set imgbbApiKey <your-key> # Required for screenshot translation/generation
54
+ kappmaker config set openaiApiKey <your-key> # Required for generate-screenshots
55
+ kappmaker config set templateRepo <your-repo> # Use your own template (default: KAppMaker)
56
+ ```
57
+
58
+ See [all config keys](#config-keys) and [external services setup](#external-services--api-keys) for details.
59
+
60
+ ## Claude Code Skill
61
+
62
+ If you use [Claude Code](https://claude.ai/code), you can install the `/kappmaker` skill to run any CLI command through natural language — with automatic prerequisite checks, guided setup, and inline error recovery.
63
+
64
+ **Install:**
65
+
66
+ ```bash
67
+ npx skills add KAppMaker/KAppMaker-CLI --skill kappmaker
68
+ ```
69
+
70
+ Or via the Claude Code plugin system:
71
+
72
+ ```
73
+ /plugin marketplace add KAppMaker/KAppMaker-CLI
74
+ /plugin install kappmaker@KAppMaker-CLI
75
+ ```
76
+
77
+ **Use:**
78
+
79
+ ```
80
+ /kappmaker create MyApp
81
+ /kappmaker generate screenshots for my fitness app
82
+ /kappmaker set up App Store Connect
83
+ ```
84
+
85
+ Claude will check your config, verify API keys are set, and walk you through any missing prerequisites before running the command.
86
+
87
+ ## Table of Contents
88
+
89
+ - [Claude Code Skill](#claude-code-skill)
90
+ - [Configuration](#configuration)
91
+ - [Commands Overview](#commands-overview)
92
+ - [Features](#features)
93
+ - [Prerequisites](#prerequisites)
94
+ - [External Services & API Keys](#external-services--api-keys)
95
+ - [Commands](#commands)
96
+ - [`create <app-name>`](#create-app-name)
97
+ - [`create-logo`](#create-logo)
98
+ - [`create-appstore-app`](#create-appstore-app)
99
+ - [`adapty setup`](#adapty-setup)
100
+ - [Image Tools](#image-tools)
101
+ - [`translate-screenshots`](#translate-screenshots-source-dir)
102
+ - [`generate-screenshots`](#generate-screenshots)
103
+ - [`publish`](#publish)
104
+ - [`generate-keystore`](#generate-keystore)
105
+ - [`android-release-build`](#android-release-build)
106
+ - [`refactor`](#refactor)
107
+ - [`update-version`](#update-version)
108
+ - [Config Reference](#config-reference)
109
+ - [Project Structure](#project-structure)
30
110
 
31
111
  ## Commands Overview
32
112
 
@@ -41,8 +121,38 @@ The `create` command runs the full end-to-end setup. Some steps assume the [KApp
41
121
  | [`kappmaker image-enhance <image>`](#image-enhance-source) | Upscale and enhance image quality (fal.ai) |
42
122
  | [`kappmaker translate-screenshots [dir]`](#translate-screenshots-source-dir) | Translate screenshots to multiple locales (fal.ai) |
43
123
  | [`kappmaker generate-screenshots`](#generate-screenshots) | Generate marketing screenshots with AI (OpenAI + fal.ai) |
124
+ | [`kappmaker publish`](#publish) | Build and upload to Google Play and/or App Store via Fastlane |
125
+ | [`kappmaker generate-keystore`](#generate-keystore) | Generate an Android signing keystore for Play Store releases |
126
+ | [`kappmaker android-release-build`](#android-release-build) | Build a signed Android release AAB |
127
+ | [`kappmaker refactor`](#refactor) | Refactor package names, application ID, bundle ID, and app name |
128
+ | [`kappmaker update-version`](#update-version) | Bump Android and iOS version codes and version name |
44
129
  | [`kappmaker config`](#config) | Manage CLI settings, API keys, and global defaults |
45
130
 
131
+ ## Features
132
+
133
+ ### Works with any project
134
+
135
+ These commands are standalone and don't depend on any specific boilerplate:
136
+
137
+ - **AI logo generation** — Generate logo variations with fal.ai, pick your favorite, auto-remove background
138
+ - **AI screenshot generation** — Generate marketing screenshots from a text description (8 style presets)
139
+ - **Screenshot translation** — Translate app screenshots to 48+ locales in parallel
140
+ - **App Store Connect setup** — Register bundle ID, create app, set metadata, categories, age rating, subscriptions, privacy, and review info
141
+ - **Adapty subscription setup** — Create products, paywalls, and placements for iOS and Android
142
+ - **Version bumping** — Increment Android and iOS version codes and names in one command
143
+ - **Image tools** — Split grids, remove backgrounds, enhance quality
144
+
145
+ ### KAppMaker boilerplate-specific
146
+
147
+ The `create` command runs the full end-to-end setup. Some steps assume the [KAppMaker](https://kappmaker.com) project structure and will be skipped with a warning if you use a custom template:
148
+
149
+ - **Package refactor** — Renames package name, app ID, and display name using the TypeScript refactor service (also available standalone via `kappmaker refactor`)
150
+ - **Firebase SDK config placement** — Downloads `google-services.json` and `GoogleService-Info.plist` to KAppMaker-specific paths (falls back to `Assets/` for custom templates)
151
+ - **Build environment** — Creates `local.properties` and runs CocoaPods in the `MobileApp/` directory
152
+ - **Android release build** — Generates keystore and builds signed AAB (also available standalone via `kappmaker android-release-build`)
153
+ - **Git remotes** — Renames origin to upstream (designed for the "fork from template" workflow)
154
+ - **Screenshot translation default path** — Defaults to `MobileApp/distribution/ios/appstore_metadata/screenshots/en-US` (falls back to parent of source directory)
155
+
46
156
  ---
47
157
 
48
158
  ## Prerequisites
@@ -87,9 +197,9 @@ The CLI integrates with several external services for AI image generation, app s
87
197
  2. Go to [API Keys](https://platform.openai.com/api-keys) and create a new key
88
198
  3. `kappmaker config set openaiApiKey <your-key>`
89
199
 
90
- ### App Store Connect CLI (asc) — iOS App Management
200
+ ### App Store Connect CLI (asc) — iOS App Management & Publishing
91
201
 
92
- **Used for:** Creating apps, setting metadata, categories, subscriptions, privacy declarations, and review info on App Store Connect.
202
+ **Used for:** Creating apps, setting metadata, categories, subscriptions, privacy declarations, and review info on App Store Connect (`create-appstore-app`). The same API key credentials are also used by `publish --platform ios` to build and upload IPAs via Fastlane.
93
203
 
94
204
  **How to set up:**
95
205
  1. Install: `brew install asc`
@@ -103,6 +213,8 @@ The CLI integrates with several external services for AI image generation, app s
103
213
  ```
104
214
  Or run `kappmaker config appstore-defaults --init` for interactive setup.
105
215
 
216
+ > **Note:** `kappmaker publish --platform ios` uses `ascKeyId`, `ascIssuerId`, and `ascPrivateKeyPath` to automatically generate the Fastlane-format publisher JSON — no separate credentials needed.
217
+
106
218
  ### Adapty CLI — Subscription Management
107
219
 
108
220
  **Used for:** Setting up in-app subscription products, paywalls, and placements across iOS and Android via Adapty's backend.
@@ -120,26 +232,40 @@ The CLI integrates with several external services for AI image generation, app s
120
232
  1. Install: `npm install -g firebase-tools`
121
233
  2. The `create` command handles login and project creation interactively.
122
234
 
123
- ---
235
+ ### Google Play Publisher — Android Store Uploads
124
236
 
125
- ## Installation
237
+ **Used for:** Building and uploading Android AABs to Google Play Store, managing Play Store metadata and screenshots via `kappmaker publish --platform android`.
126
238
 
127
- ```bash
128
- npm install -g kappmaker
129
- ```
239
+ **How to set up:**
130
240
 
131
- Then use it anywhere:
241
+ 1. Go to [Google Cloud Console](https://console.cloud.google.com) and create a new project (or select existing)
242
+ 2. Open **APIs & Services > Library**, search for **Google Play Android Developer API**, and enable it
243
+ 3. Go to **IAM & Admin > Service Accounts**, create a new service account (skip role assignment)
244
+ 4. Open the service account, go to **Keys**, click **Add key > Create new key > JSON**, and download it
245
+ 5. Open [Google Play Console](https://play.google.com/console), go to **Settings > Users and permissions**
246
+ 6. Click **Invite new user** with the service account email (`...@...iam.gserviceaccount.com`) and grant permissions for your app(s)
247
+ 7. Save the JSON key file and configure:
248
+ ```bash
249
+ kappmaker config set googleServiceAccountPath /path/to/google-service-app-publisher.json
250
+ ```
132
251
 
133
- ```bash
134
- kappmaker create <AppName>
135
- ```
252
+ ### App Store Publisher — iOS Store Uploads
136
253
 
137
- ### Development
254
+ **Used for:** Building and uploading iOS IPAs to App Store Connect, managing App Store metadata and screenshots via `kappmaker publish --platform ios`.
138
255
 
139
- ```bash
140
- npm install
141
- npx tsx src/index.ts create <AppName>
142
- ```
256
+ The `publish` command reuses the same App Store Connect API key credentials used by `create-appstore-app` (`ascKeyId`, `ascIssuerId`, `ascPrivateKeyPath`) and automatically generates the Fastlane-format publisher JSON.
257
+
258
+ **How to set up** (if not already configured for `create-appstore-app`):
259
+
260
+ 1. Open [App Store Connect > Users and Access > Integrations](https://appstoreconnect.apple.com/access/integrations/api)
261
+ 2. Create an API key with **App Manager** access and download the `.p8` file
262
+ 3. Note the **Key ID** and **Issuer ID**
263
+ 4. Configure:
264
+ ```bash
265
+ kappmaker config set ascKeyId <your-key-id>
266
+ kappmaker config set ascIssuerId <your-issuer-id>
267
+ kappmaker config set ascPrivateKeyPath /path/to/AuthKey.p8
268
+ ```
143
269
 
144
270
  ---
145
271
 
@@ -164,10 +290,10 @@ kappmaker create Remimi
164
290
  | 7 | Logo generation | *Optional* — AI logo + automatic background removal |
165
291
  | 8 | App Store Connect | *Optional* — full app setup (metadata, subs, privacy) |
166
292
  | 9 | Adapty setup | *Optional* — products, paywalls, placements |
167
- | 10 | Gradle refactor | Sets app name + application ID; *skipped with warning if `refactorPackage` task not found* |
293
+ | 10 | Package refactor | Sets package name, application ID, bundle ID, and app name (TypeScript) |
168
294
  | 11 | Build environment | Creates `local.properties`, installs CocoaPods; *skipped with warning if `gradlew`/`Podfile` not found* |
169
295
  | 12 | Git remotes | Renames origin to upstream |
170
- | 13 | Android release build | Fastlane build, prints AAB path; *skipped with warning if `Fastfile` not found* |
296
+ | 13 | Android release build | Generates keystore if needed, builds signed AAB; *skipped if `gradlew` not found* |
171
297
 
172
298
  **Options:**
173
299
 
@@ -479,9 +605,147 @@ Requires: `falApiKey`, `openaiApiKey`, and `imgbbApiKey` (if using reference ima
479
605
 
480
606
  ---
481
607
 
482
- ## `config`
608
+ ## `publish`
609
+
610
+ Builds and uploads your app to Google Play and/or App Store using Fastlane.
611
+
612
+ ```bash
613
+ kappmaker publish # Both platforms
614
+ kappmaker publish --platform android # Android only
615
+ kappmaker publish --platform ios # iOS only
616
+ kappmaker publish --platform android --platform ios # Both explicitly
617
+ kappmaker publish --platform android --track internal # Android internal track
618
+ kappmaker publish --upload-metadata --upload-screenshots # With metadata
619
+ ```
620
+
621
+ Run from the project root (containing `MobileApp/`) or inside `MobileApp/` directly. Requires Fastlane via Bundler (`Gemfile` + `fastlane/Fastfile`).
622
+
623
+ **Prerequisites:**
624
+ - **Android:** Google Play service account JSON — see [Google Play Publisher setup](#google-play-publisher--android-store-uploads)
625
+ - **iOS:** App Store Connect API key — see [App Store Publisher setup](#app-store-publisher--ios-store-uploads). The CLI generates the Fastlane-format publisher JSON automatically from your `ascKeyId`/`ascIssuerId`/`ascPrivateKeyPath` config.
626
+
627
+ | Flag | Description | Default |
628
+ |------|-------------|---------|
629
+ | `--platform <name>` | Platform to publish: `android`, `ios` (repeatable) | Both |
630
+ | `--track <name>` | Android Play Store track (internal/alpha/beta/production) | `production` |
631
+ | `--upload-metadata` | Upload metadata (title, description) | `false` |
632
+ | `--upload-screenshots` | Upload screenshots | `false` |
633
+ | `--upload-images` | Upload images — icon, feature graphic (Android only) | `false` |
634
+ | `--submit-for-review` | Submit for review after upload | `true` |
635
+
636
+ ---
637
+
638
+ ## `generate-keystore`
639
+
640
+ Generates an Android signing keystore for Play Store releases. Creates `keystore.jks` and `keystore.properties` with a secure random password.
641
+
642
+ ```bash
643
+ kappmaker generate-keystore --organization "MyCompany"
644
+ kappmaker generate-keystore --first-name "John Doe" --organization "MyCompany"
645
+ kappmaker generate-keystore --output ./custom-keystore-dir
646
+ ```
647
+
648
+ Run from the project root (containing `MobileApp/`) or inside `MobileApp/` directly.
649
+
650
+ **Output** (default: `distribution/android/keystore/` inside MobileApp):
651
+ - `keystore.jks` — the signing keystore
652
+ - `keystore.properties` — password, alias, and store file path
653
+
654
+ At least one of `--first-name` or `--organization` is required.
655
+
656
+ | Flag | Description | Required |
657
+ |------|-------------|----------|
658
+ | `--first-name <name>` | Developer name for keystore | One of these |
659
+ | `--organization <name>` | Organization name for keystore | is required |
660
+ | `--output <dir>` | Output directory for keystore files | No |
661
+
662
+ ---
663
+
664
+ ## `android-release-build`
665
+
666
+ Builds a signed Android release AAB. Automatically generates a keystore if one doesn't exist yet.
667
+
668
+ ```bash
669
+ kappmaker android-release-build
670
+ kappmaker android-release-build --organization "MyCompany"
671
+ kappmaker android-release-build --output ./my-output
672
+ ```
673
+
674
+ Run from the project root (containing `MobileApp/`) or inside `MobileApp/` directly. Requires `gradlew` in the mobile app directory.
675
+
676
+ **What it does:**
677
+ 1. Generates keystore if `distribution/android/keystore/keystore.properties` doesn't exist
678
+ 2. Runs `./gradlew :composeApp:bundleRelease`
679
+ 3. Copies the AAB to the output directory
680
+
681
+ **Output:** `distribution/android/app-release.aab` (or custom `--output` path)
682
+
683
+ | Flag | Description | Default |
684
+ |------|-------------|---------|
685
+ | `--organization <name>` | Organization for keystore generation | From config |
686
+ | `--first-name <name>` | Developer name for keystore generation | Empty |
687
+ | `--output <dir>` | Output directory for AAB | `distribution/android` |
688
+
689
+ ---
690
+
691
+ ## `refactor`
692
+
693
+ Refactors package names, application ID, bundle ID, and app name across the entire project. Implemented in TypeScript — no Gradle build system required.
694
+
695
+ ```bash
696
+ kappmaker refactor --app-id com.example.myapp --app-name MyApp
697
+ kappmaker refactor --app-id com.example.myapp --app-name MyApp --skip-package-rename
698
+ ```
699
+
700
+ Run from the project root (containing `MobileApp/`) or from inside `MobileApp/` directly.
701
+
702
+ **Full refactor (default):**
703
+ 1. Renames Kotlin package names in all source sets (commonMain, androidMain, iosMain, etc.)
704
+ 2. Moves package directories to match the new package structure
705
+ 3. Updates Gradle build files, Firebase configs, iOS project files, and GitHub workflows
706
+ 4. Updates the app display name in manifests, settings, and platform-specific files
707
+
708
+ **Skip-package-rename mode (`--skip-package-rename`):**
709
+ Only updates `applicationId` / bundle ID, Firebase configs, iOS files, GitHub workflows, and app name — keeps Kotlin package directories intact. Useful for creating multiple apps from one codebase without merge conflicts.
710
+
711
+ | Flag | Description | Required |
712
+ |------|-------------|----------|
713
+ | `--app-id <id>` | New applicationId / bundleId (e.g., `com.example.myapp`) | Yes |
714
+ | `--app-name <name>` | New display name (e.g., `MyApp`) | Yes |
715
+ | `--old-app-id <id>` | Current applicationId to replace (default: `com.measify.kappmaker`) | No |
716
+ | `--old-app-name <name>` | Current app name to replace (default: `KAppMakerAllModules`) | No |
717
+ | `--skip-package-rename` | Keep Kotlin package dirs, only update IDs and app name | No |
718
+
719
+ ---
720
+
721
+ ## `update-version`
722
+
723
+ Bumps Android and iOS version codes and optionally sets a new version name. Run from the project root (containing `MobileApp/`) or from inside `MobileApp/` directly.
724
+
725
+ ```bash
726
+ kappmaker update-version # Increment patch: 1.2.3 → 1.2.4, versionCode +1
727
+ kappmaker update-version -v 2.0.0 # Set explicit version name, versionCode +1
728
+ ```
729
+
730
+ **What it updates:**
731
+
732
+ | Platform | File | Fields |
733
+ |----------|------|--------|
734
+ | Android | `composeApp/build.gradle.kts` | `versionCode`, `versionName` |
735
+ | iOS | `iosApp/iosApp.xcodeproj/project.pbxproj` | `CURRENT_PROJECT_VERSION`, `MARKETING_VERSION` |
736
+ | iOS | `iosApp/iosApp/Info.plist` | `CFBundleVersion`, `CFBundleShortVersionString` |
737
+
738
+ If a platform's files are missing, that platform is skipped with a warning.
739
+
740
+ | Flag | Description | Default |
741
+ |------|-------------|---------|
742
+ | `-v, --version <name>` | Set explicit version name (e.g., `2.0.0`) | Auto-increment patch |
743
+
744
+ ---
745
+
746
+ ## Config Reference
483
747
 
484
- Manage CLI configuration stored at `~/.config/kappmaker/config.json`.
748
+ Configuration is stored at `~/.config/kappmaker/config.json`.
485
749
 
486
750
  ```bash
487
751
  kappmaker config init # Interactive setup
@@ -512,6 +776,7 @@ kappmaker config adapty-defaults --save ./config.json # Save as global defaul
512
776
  | `ascIssuerId` | App Store Connect Issuer ID | — |
513
777
  | `ascPrivateKeyPath` | Path to `.p8` private key | — |
514
778
  | `appleId` | Apple ID email (for privacy setup) | — |
779
+ | `googleServiceAccountPath` | Google Play service account JSON path | `~/credentials/google-service-app-publisher.json` |
515
780
 
516
781
  ### Global defaults
517
782
 
@@ -540,6 +805,11 @@ src/
540
805
  enhance.ts # Image quality enhancement
541
806
  translate-screenshots.ts # Screenshot translation
542
807
  generate-screenshots.ts # AI screenshot generation
808
+ publish.ts # Build and upload to Play Store / App Store
809
+ generate-keystore.ts # Generate Android signing keystore
810
+ android-release-build.ts # Build signed Android release AAB
811
+ refactor.ts # Package/app name refactoring
812
+ update-version.ts # Bump Android + iOS version codes and version name
543
813
  config.ts # Config management
544
814
  services/
545
815
  firebase.service.ts # Firebase CLI wrapper + anonymous auth
@@ -549,12 +819,16 @@ src/
549
819
  asc-monetization.service.ts # ASC pricing, subscriptions, IAP
550
820
  adapty.service.ts # Adapty CLI wrapper
551
821
  git.service.ts # Git operations
552
- gradle.service.ts # Gradle build operations
822
+ publish.service.ts # Android/iOS publishing via Fastlane
823
+ keystore.service.ts # Android keystore generation
824
+ gradle.service.ts # Gradle build helpers (local.properties, clean & build)
553
825
  ios.service.ts # CocoaPods setup
554
- fastlane.service.ts # Fastlane build + AAB finder
826
+ fastlane.service.ts # Android release build (keystore + gradle) + AAB finder
555
827
  logo.service.ts # Logo prompt builder + image extraction
556
828
  screenshot.service.ts # Screenshot grid operations + Fastlane output
557
829
  screenshot-styles.ts # Screenshot style prompts (8 styles)
830
+ refactor.service.ts # Package/app name refactoring logic
831
+ version.service.ts # Android + iOS version reading/writing
558
832
  utils/
559
833
  logger.ts # Chalk-based logging
560
834
  exec.ts # Command execution (execa + ora)
package/dist/cli.js CHANGED
@@ -9,6 +9,11 @@ import { configList, configGet, configSet, configPath, configInit, configAppStor
9
9
  import { createAppStoreApp } from './commands/create-appstore-app.js';
10
10
  import { generateScreenshots } from './commands/generate-screenshots.js';
11
11
  import { adaptySetup } from './commands/adapty-setup.js';
12
+ import { updateVersion } from './commands/update-version.js';
13
+ import { refactorCommand } from './commands/refactor.js';
14
+ import { generateKeystoreCommand } from './commands/generate-keystore.js';
15
+ import { androidReleaseBuild } from './commands/android-release-build.js';
16
+ import { publishCommand } from './commands/publish.js';
12
17
  export function createCli() {
13
18
  const program = new Command();
14
19
  program
@@ -138,6 +143,61 @@ export function createCli() {
138
143
  .action(async (options) => {
139
144
  await adaptySetup(options);
140
145
  });
146
+ // ── Android Build ──────────────────────────────────────────────────
147
+ program
148
+ .command('generate-keystore')
149
+ .description('Generate an Android signing keystore for Play Store releases')
150
+ .option('--first-name <name>', 'Developer name for keystore')
151
+ .option('--organization <name>', 'Organization name for keystore')
152
+ .option('--output <dir>', 'Output directory for keystore files')
153
+ .action(async (options) => {
154
+ await generateKeystoreCommand(options);
155
+ });
156
+ program
157
+ .command('android-release-build')
158
+ .description('Build a signed Android release AAB (generates keystore if needed)')
159
+ .option('--organization <name>', 'Organization name for keystore generation')
160
+ .option('--first-name <name>', 'Developer name for keystore generation')
161
+ .option('--output <dir>', 'Output directory for AAB (default: distribution/android)')
162
+ .action(async (options) => {
163
+ await androidReleaseBuild(options);
164
+ });
165
+ // ── Publish ────────────────────────────────────────────────────────
166
+ function collect(value, previous) {
167
+ return previous.concat([value]);
168
+ }
169
+ program
170
+ .command('publish')
171
+ .description('Build and upload app to Google Play and/or App Store via Fastlane')
172
+ .option('--platform <name>', 'Platform to publish: android, ios (repeatable)', collect, [])
173
+ .option('--track <name>', 'Android Play Store track (internal/alpha/beta/production)', 'production')
174
+ .option('--upload-metadata', 'Upload metadata (title, description)', false)
175
+ .option('--upload-screenshots', 'Upload screenshots', false)
176
+ .option('--upload-images', 'Upload images — icon, feature graphic (Android only)', false)
177
+ .option('--submit-for-review', 'Submit for review after upload', true)
178
+ .action(async (options) => {
179
+ await publishCommand(options);
180
+ });
181
+ // ── Refactor ───────────────────────────────────────────────────────
182
+ program
183
+ .command('refactor')
184
+ .description('Refactor package names, application ID, bundle ID, and app name')
185
+ .requiredOption('--app-id <id>', 'New applicationId / bundleId (e.g., com.example.myapp)')
186
+ .requiredOption('--app-name <name>', 'New display name (e.g., MyApp)')
187
+ .option('--old-app-id <id>', 'Current applicationId to replace (default: com.measify.kappmaker)')
188
+ .option('--old-app-name <name>', 'Current app name to replace (default: KAppMakerAllModules)')
189
+ .option('--skip-package-rename', 'Only update applicationId/bundleId/app name, keep Kotlin package dirs intact')
190
+ .action(async (options) => {
191
+ await refactorCommand(options);
192
+ });
193
+ // ── Version ────────────────────────────────────────────────────────
194
+ program
195
+ .command('update-version')
196
+ .description('Bump Android and iOS version codes and optionally set version name')
197
+ .option('-v, --version <name>', 'Set explicit version name (e.g., "2.0.0")')
198
+ .action(async (options) => {
199
+ await updateVersion(options);
200
+ });
141
201
  // ── Config ─────────────────────────────────────────────────────────
142
202
  const config = program
143
203
  .command('config')
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ interface AndroidReleaseBuildOptions {
2
+ organization?: string;
3
+ firstName?: string;
4
+ output?: string;
5
+ }
6
+ export declare function androidReleaseBuild(options: AndroidReleaseBuildOptions): Promise<void>;
7
+ export {};
@@ -0,0 +1,51 @@
1
+ import path from 'path';
2
+ import fs from 'fs-extra';
3
+ import chalk from 'chalk';
4
+ import { logger } from '../utils/logger.js';
5
+ import { resolveMobileDir } from '../services/version.service.js';
6
+ import { hasKeystore, generateKeystore } from '../services/keystore.service.js';
7
+ import { loadConfig } from '../utils/config.js';
8
+ import { run } from '../utils/exec.js';
9
+ export async function androidReleaseBuild(options) {
10
+ const mobileDir = resolveMobileDir();
11
+ const gradlewPath = path.join(mobileDir, 'gradlew');
12
+ if (!(await fs.pathExists(gradlewPath))) {
13
+ logger.error('gradlew not found — cannot build Android release.');
14
+ process.exit(1);
15
+ }
16
+ // Ensure keystore exists
17
+ if (!(await hasKeystore(mobileDir))) {
18
+ logger.info('Keystore not found — generating a new one...');
19
+ const userConfig = await loadConfig();
20
+ const organization = options.organization || userConfig.organization;
21
+ const firstName = options.firstName ?? '';
22
+ if (!organization && !firstName) {
23
+ logger.error('No keystore found. Provide --organization or --first-name to generate one, or set "organization" in config.');
24
+ process.exit(1);
25
+ }
26
+ await generateKeystore(mobileDir, firstName, organization || '', options.output);
27
+ }
28
+ // Build AAB
29
+ await run('./gradlew', [':composeApp:bundleRelease'], {
30
+ cwd: mobileDir,
31
+ label: 'Building Android release AAB (this may take a few minutes)',
32
+ });
33
+ // Copy AAB to output directory
34
+ const builtAab = path.join(mobileDir, 'composeApp', 'build', 'outputs', 'bundle', 'release', 'composeApp-release.aab');
35
+ if (!(await fs.pathExists(builtAab))) {
36
+ logger.error(`AAB not found at expected path: ${builtAab}`);
37
+ process.exit(1);
38
+ }
39
+ const outputDir = options.output
40
+ ? path.resolve(options.output)
41
+ : path.join(mobileDir, 'distribution', 'android');
42
+ await fs.ensureDir(outputDir);
43
+ const outputPath = path.join(outputDir, 'app-release.aab');
44
+ await fs.copy(builtAab, outputPath, { overwrite: true });
45
+ console.log('');
46
+ console.log(chalk.green.bold(' Android App Bundle (AAB) ready!'));
47
+ console.log(chalk.cyan(` ${outputPath}`));
48
+ console.log(chalk.gray(' Upload this file to Google Play Console to publish your app.'));
49
+ console.log('');
50
+ }
51
+ //# sourceMappingURL=android-release-build.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"android-release-build.js","sourceRoot":"","sources":["../../src/commands/android-release-build.ts"],"names":[],"mappings":"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"}