@daemux/store-automator 0.5.2 → 0.5.3
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/.claude-plugin/marketplace.json +2 -2
- package/README.md +50 -4
- package/bin/cli.mjs +51 -26
- package/package.json +1 -1
- package/plugins/store-automator/agents/devops.md +44 -54
- package/src/install.mjs +2 -2
- package/src/mcp-setup.mjs +9 -1
- package/src/prompt.mjs +46 -20
- package/templates/CLAUDE.md.template +1 -1
- package/templates/ci.config.yaml.template +1 -2
|
@@ -5,14 +5,14 @@
|
|
|
5
5
|
},
|
|
6
6
|
"metadata": {
|
|
7
7
|
"description": "App Store & Google Play automation for Flutter apps",
|
|
8
|
-
"version": "0.5.
|
|
8
|
+
"version": "0.5.3"
|
|
9
9
|
},
|
|
10
10
|
"plugins": [
|
|
11
11
|
{
|
|
12
12
|
"name": "store-automator",
|
|
13
13
|
"source": "./plugins/store-automator",
|
|
14
14
|
"description": "3 agents for app store publishing: reviewer, meta-creator, media-designer",
|
|
15
|
-
"version": "0.5.
|
|
15
|
+
"version": "0.5.3",
|
|
16
16
|
"keywords": ["flutter", "app-store", "google-play", "fastlane", "codemagic"]
|
|
17
17
|
}
|
|
18
18
|
]
|
package/README.md
CHANGED
|
@@ -27,8 +27,8 @@ npm install @daemux/store-automator
|
|
|
27
27
|
|
|
28
28
|
The postinstall script will:
|
|
29
29
|
|
|
30
|
-
1. Prompt for MCP server tokens (Stitch, Cloudflare)
|
|
31
|
-
2. Configure `.mcp.json` with MCP servers (Playwright, mobile-mcp, Stitch, Cloudflare)
|
|
30
|
+
1. Prompt for MCP server tokens (Stitch, Cloudflare, Codemagic)
|
|
31
|
+
2. Configure `.mcp.json` with MCP servers (Playwright, mobile-mcp, Stitch, Cloudflare, Codemagic)
|
|
32
32
|
3. Install the plugin marketplace and register agents
|
|
33
33
|
4. Copy `CLAUDE.md` template to `.claude/CLAUDE.md`
|
|
34
34
|
5. Copy CI/CD templates (Fastlane, scripts, web pages, ci.config.yaml)
|
|
@@ -112,8 +112,54 @@ The package configures these MCP servers in `.mcp.json`:
|
|
|
112
112
|
|--------|---------|---------------|
|
|
113
113
|
| playwright | Browser automation for testing web pages | None |
|
|
114
114
|
| mobile-mcp | Mobile device automation | None |
|
|
115
|
-
| stitch | AI design tool for screenshot generation |
|
|
116
|
-
| cloudflare | Cloudflare Pages deployment |
|
|
115
|
+
| stitch | AI design tool for screenshot generation | `STITCH_API_KEY` |
|
|
116
|
+
| cloudflare | Cloudflare Pages deployment | `CLOUDFLARE_API_TOKEN` + Account ID |
|
|
117
|
+
| codemagic | Codemagic CI/CD build management (27 tools) | `CODEMAGIC_API_TOKEN` |
|
|
118
|
+
|
|
119
|
+
## Non-interactive Install
|
|
120
|
+
|
|
121
|
+
For CI/CD environments or scripted setups, pass tokens as CLI flags to skip interactive prompts:
|
|
122
|
+
|
|
123
|
+
```bash
|
|
124
|
+
npx @daemux/store-automator \
|
|
125
|
+
--codemagic-token=YOUR_CM_TOKEN \
|
|
126
|
+
--stitch-key=YOUR_STITCH_KEY \
|
|
127
|
+
--cloudflare-token=YOUR_CF_TOKEN \
|
|
128
|
+
--cloudflare-account-id=YOUR_CF_ACCOUNT_ID
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
Any tokens provided via flags will skip the corresponding interactive prompt. If all four tokens are provided, the entire interactive session is skipped.
|
|
132
|
+
|
|
133
|
+
## CLI Options
|
|
134
|
+
|
|
135
|
+
```
|
|
136
|
+
Usage: npx @daemux/store-automator [options]
|
|
137
|
+
|
|
138
|
+
Options:
|
|
139
|
+
-g, --global Install globally (~/.claude) instead of project scope
|
|
140
|
+
-u, --uninstall Uninstall plugin and remove files
|
|
141
|
+
--postinstall Run as postinstall hook (auto-detected)
|
|
142
|
+
-v, --version Show version number
|
|
143
|
+
-h, --help Show help
|
|
144
|
+
|
|
145
|
+
MCP Token Flags (skip interactive prompts):
|
|
146
|
+
--codemagic-token=TOKEN Codemagic API token
|
|
147
|
+
--stitch-key=KEY Stitch MCP API key
|
|
148
|
+
--cloudflare-token=TOKEN Cloudflare API token
|
|
149
|
+
--cloudflare-account-id=ID Cloudflare account ID
|
|
150
|
+
|
|
151
|
+
Codemagic:
|
|
152
|
+
--codemagic-setup Register repo and optionally trigger build
|
|
153
|
+
--token=TOKEN API token (or set CM_API_TOKEN env var)
|
|
154
|
+
--branch=BRANCH Branch to build (default: main)
|
|
155
|
+
--workflow=ID Workflow ID (default: default)
|
|
156
|
+
--trigger Trigger build after setup
|
|
157
|
+
--wait Wait for build completion (implies --trigger)
|
|
158
|
+
|
|
159
|
+
GitHub Actions:
|
|
160
|
+
--github-setup Set CM_API_TOKEN secret for GitHub Actions
|
|
161
|
+
--token=TOKEN API token (or set CM_API_TOKEN env var)
|
|
162
|
+
```
|
|
117
163
|
|
|
118
164
|
## License
|
|
119
165
|
|
package/bin/cli.mjs
CHANGED
|
@@ -21,19 +21,34 @@ let cmWorkflowId = 'default';
|
|
|
21
21
|
let cmTrigger = false;
|
|
22
22
|
let cmWait = false;
|
|
23
23
|
|
|
24
|
+
const cliTokens = {};
|
|
25
|
+
|
|
26
|
+
function flagValue(arg, prefix) {
|
|
27
|
+
return arg.startsWith(prefix) ? arg.slice(prefix.length) : undefined;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const tokenFlags = {
|
|
31
|
+
'--codemagic-token=': 'codemagicToken',
|
|
32
|
+
'--stitch-key=': 'stitchApiKey',
|
|
33
|
+
'--cloudflare-token=': 'cloudflareToken',
|
|
34
|
+
'--cloudflare-account-id=': 'cloudflareAccountId',
|
|
35
|
+
};
|
|
36
|
+
|
|
24
37
|
for (const arg of args) {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
38
|
+
let v;
|
|
39
|
+
if ((v = flagValue(arg, '--token=')) !== undefined) { cmTokenArg = v; continue; }
|
|
40
|
+
if ((v = flagValue(arg, '--branch=')) !== undefined) { cmBranch = v; continue; }
|
|
41
|
+
if ((v = flagValue(arg, '--workflow=')) !== undefined) { cmWorkflowId = v; continue; }
|
|
42
|
+
|
|
43
|
+
let matched = false;
|
|
44
|
+
for (const [prefix, key] of Object.entries(tokenFlags)) {
|
|
45
|
+
if ((v = flagValue(arg, prefix)) !== undefined) {
|
|
46
|
+
cliTokens[key] = v;
|
|
47
|
+
matched = true;
|
|
48
|
+
break;
|
|
49
|
+
}
|
|
36
50
|
}
|
|
51
|
+
if (matched) continue;
|
|
37
52
|
|
|
38
53
|
switch (arg) {
|
|
39
54
|
case '-g':
|
|
@@ -64,23 +79,29 @@ for (const arg of args) {
|
|
|
64
79
|
console.log(`Usage: npx @daemux/store-automator [options]
|
|
65
80
|
|
|
66
81
|
Options:
|
|
67
|
-
-g, --global
|
|
68
|
-
-u, --uninstall
|
|
69
|
-
--postinstall
|
|
70
|
-
-v, --version
|
|
71
|
-
-h, --help
|
|
82
|
+
-g, --global Install globally (~/.claude) instead of project scope
|
|
83
|
+
-u, --uninstall Uninstall plugin and remove files
|
|
84
|
+
--postinstall Run as postinstall hook (auto-detected)
|
|
85
|
+
-v, --version Show version number
|
|
86
|
+
-h, --help Show help
|
|
87
|
+
|
|
88
|
+
MCP Token Flags (skip interactive prompts):
|
|
89
|
+
--codemagic-token=TOKEN Codemagic API token
|
|
90
|
+
--stitch-key=KEY Stitch MCP API key
|
|
91
|
+
--cloudflare-token=TOKEN Cloudflare API token
|
|
92
|
+
--cloudflare-account-id=ID Cloudflare account ID
|
|
72
93
|
|
|
73
94
|
Codemagic:
|
|
74
|
-
--codemagic-setup
|
|
75
|
-
--token=TOKEN
|
|
76
|
-
--branch=BRANCH
|
|
77
|
-
--workflow=ID
|
|
78
|
-
--trigger
|
|
79
|
-
--wait
|
|
95
|
+
--codemagic-setup Register repo and optionally trigger build
|
|
96
|
+
--token=TOKEN API token (or set CM_API_TOKEN env var)
|
|
97
|
+
--branch=BRANCH Branch to build (default: main)
|
|
98
|
+
--workflow=ID Workflow ID (default: default)
|
|
99
|
+
--trigger Trigger build after setup
|
|
100
|
+
--wait Wait for build completion (implies --trigger)
|
|
80
101
|
|
|
81
102
|
GitHub Actions (auto-configured during install if gh CLI available):
|
|
82
|
-
--github-setup
|
|
83
|
-
--token=TOKEN
|
|
103
|
+
--github-setup Set CM_API_TOKEN secret for GitHub Actions
|
|
104
|
+
--token=TOKEN API token (or set CM_API_TOKEN env var)
|
|
84
105
|
|
|
85
106
|
Examples:
|
|
86
107
|
npx @daemux/store-automator Install for project
|
|
@@ -89,7 +110,11 @@ Examples:
|
|
|
89
110
|
npx @daemux/store-automator -g -u Uninstall globally
|
|
90
111
|
npx @daemux/store-automator --codemagic-setup Register with Codemagic
|
|
91
112
|
npx @daemux/store-automator --codemagic-setup --trigger --wait Trigger and wait
|
|
92
|
-
npx @daemux/store-automator --github-setup Configure GitHub Actions
|
|
113
|
+
npx @daemux/store-automator --github-setup Configure GitHub Actions
|
|
114
|
+
|
|
115
|
+
Non-interactive install (CI/CD):
|
|
116
|
+
npx @daemux/store-automator --codemagic-token=TOKEN --stitch-key=KEY
|
|
117
|
+
npx @daemux/store-automator --cloudflare-token=TOKEN --cloudflare-account-id=ID`);
|
|
93
118
|
process.exit(0);
|
|
94
119
|
break; // eslint: no-fallthrough
|
|
95
120
|
case '-v':
|
|
@@ -122,7 +147,7 @@ try {
|
|
|
122
147
|
await runUninstall(scope);
|
|
123
148
|
} else {
|
|
124
149
|
const { runInstall } = await import('../src/install.mjs');
|
|
125
|
-
await runInstall(scope, isPostinstall);
|
|
150
|
+
await runInstall(scope, isPostinstall, cliTokens);
|
|
126
151
|
}
|
|
127
152
|
} catch (err) {
|
|
128
153
|
if (isPostinstall) {
|
package/package.json
CHANGED
|
@@ -42,14 +42,9 @@ The Codemagic pipeline runs two parallel workflows on push to `main`:
|
|
|
42
42
|
**iOS Release**: Flutter analyze -> Flutter test -> Build IPA -> Code signing -> Upload metadata + screenshots -> Deploy to App Store Connect -> Sync IAP
|
|
43
43
|
**Android Release**: Flutter analyze -> Flutter test -> Build AAB -> Keystore signing -> Check Google Play readiness -> Deploy to Google Play -> Sync IAP
|
|
44
44
|
|
|
45
|
-
### Token
|
|
45
|
+
### Token Configuration
|
|
46
46
|
|
|
47
|
-
The Codemagic API token is
|
|
48
|
-
|
|
49
|
-
```bash
|
|
50
|
-
# Extract token from ci.config.yaml
|
|
51
|
-
CM_API_TOKEN=$(grep 'api_token:' ci.config.yaml | head -1 | sed 's/.*api_token: *"\{0,1\}\([^"]*\)"\{0,1\}/\1/' | tr -d ' ')
|
|
52
|
-
```
|
|
47
|
+
The Codemagic API token is auto-configured via the codemagic MCP server in `.mcp.json` (set during install). You do not need to resolve the token manually -- all MCP tool calls authenticate automatically. If the codemagic MCP server is missing from `.mcp.json`, instruct the user to re-run `npx @daemux/store-automator` or add `--codemagic-token=TOKEN` to configure it.
|
|
53
48
|
|
|
54
49
|
### Triggering Builds
|
|
55
50
|
|
|
@@ -59,29 +54,50 @@ git push origin main
|
|
|
59
54
|
```
|
|
60
55
|
Codemagic triggers both iOS and Android workflows automatically on push to `main`.
|
|
61
56
|
|
|
62
|
-
**Option 2: Codemagic
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
const r = await startBuild('$CM_API_TOKEN', '<appId>', '<workflowId>', 'main');
|
|
68
|
-
console.log(JSON.stringify(r, null, 2));
|
|
69
|
-
"
|
|
70
|
-
```
|
|
57
|
+
**Option 2: Codemagic MCP** (preferred for full automation -- allows status polling and log reading)
|
|
58
|
+
Use the `start_build` MCP tool:
|
|
59
|
+
- `appId`: from `codemagic.app_id` in `ci.config.yaml`
|
|
60
|
+
- `workflowId`: from `codemagic.workflows` in `ci.config.yaml`
|
|
61
|
+
- `branch`: `main` (or as needed)
|
|
71
62
|
|
|
72
63
|
### Monitoring Build Status
|
|
73
64
|
|
|
74
|
-
|
|
75
|
-
CM_API_TOKEN=$(grep 'api_token:' ci.config.yaml | head -1 | sed 's/.*api_token: *"\{0,1\}\([^"]*\)"\{0,1\}/\1/' | tr -d ' ')
|
|
76
|
-
node -e "
|
|
77
|
-
import {getBuildStatus} from './src/codemagic-api.mjs';
|
|
78
|
-
const r = await getBuildStatus('$CM_API_TOKEN', '<buildId>');
|
|
79
|
-
console.log(JSON.stringify(r, null, 2));
|
|
80
|
-
"
|
|
81
|
-
```
|
|
65
|
+
Use the `get_build` MCP tool with the `buildId` returned from `start_build`. Poll every 60 seconds until the build reaches a terminal state.
|
|
82
66
|
|
|
83
67
|
Build states: `queued` -> `preparing` -> `building` -> `testing` -> `publishing` -> `finished` | `failed` | `canceled`
|
|
84
68
|
|
|
69
|
+
### Available Codemagic MCP Tools
|
|
70
|
+
|
|
71
|
+
| Tool | Description |
|
|
72
|
+
|------|-------------|
|
|
73
|
+
| `list_apps` | List all Codemagic applications |
|
|
74
|
+
| `get_app` | Get details of a specific application |
|
|
75
|
+
| `add_app` | Add a new application to Codemagic |
|
|
76
|
+
| `start_build` | Start a new build |
|
|
77
|
+
| `get_build` | Get details of a specific build |
|
|
78
|
+
| `cancel_build` | Cancel a running build |
|
|
79
|
+
| `list_builds` | List builds for a team (V3 API) |
|
|
80
|
+
| `get_artifact_url` | Get the download URL for a build artifact |
|
|
81
|
+
| `create_public_artifact_url` | Create a time-limited public URL for an artifact |
|
|
82
|
+
| `list_caches` | List build caches for an application |
|
|
83
|
+
| `delete_caches` | Delete build caches for an application |
|
|
84
|
+
| `setup_asc_credentials` | Create variable group with App Store Connect credentials |
|
|
85
|
+
| `setup_code_signing` | Create variable group with iOS code signing cert and profile |
|
|
86
|
+
| `get_user` | Get the current authenticated user info |
|
|
87
|
+
| `list_teams` | List all teams the user belongs to |
|
|
88
|
+
| `get_team` | Get details of a specific team |
|
|
89
|
+
| `list_team_members` | List members of a specific team |
|
|
90
|
+
| `list_variable_groups` | List variable groups for a team or application |
|
|
91
|
+
| `get_variable_group` | Get details of a specific variable group |
|
|
92
|
+
| `create_variable_group` | Create a new variable group |
|
|
93
|
+
| `update_variable_group` | Update a variable group name or security setting |
|
|
94
|
+
| `delete_variable_group` | Delete a variable group |
|
|
95
|
+
| `list_variables` | List variables in a variable group |
|
|
96
|
+
| `get_variable` | Get a specific variable from a variable group |
|
|
97
|
+
| `update_variable` | Update a variable in a variable group |
|
|
98
|
+
| `delete_variable` | Delete a variable from a variable group |
|
|
99
|
+
| `bulk_import_variables` | Import multiple variables into a variable group |
|
|
100
|
+
|
|
85
101
|
### Build Failure Analysis
|
|
86
102
|
|
|
87
103
|
When a build fails:
|
|
@@ -115,24 +131,9 @@ Versions are auto-incremented:
|
|
|
115
131
|
- Build number = latest store build number + 1
|
|
116
132
|
- Both platforms share the same version name (e.g., 1.0.0), synced from iOS
|
|
117
133
|
|
|
118
|
-
### Health Check
|
|
119
|
-
|
|
120
|
-
After triggering a build:
|
|
121
|
-
1. Poll build status every 60 seconds until completion
|
|
122
|
-
2. Check both iOS and Android workflows independently
|
|
123
|
-
3. If one passes and one fails, report partial success and investigate the failure
|
|
124
|
-
4. Verify artifacts exist (IPA for iOS, AAB for Android)
|
|
125
|
-
5. Check store submission status after successful upload
|
|
126
|
-
|
|
127
|
-
### Log Analysis
|
|
134
|
+
### Health Check and Log Analysis
|
|
128
135
|
|
|
129
|
-
|
|
130
|
-
1. Look for `ERROR`, `FAILURE`, `EXCEPTION`, `BUILD FAILED` patterns
|
|
131
|
-
2. Check Flutter analyze output for lint warnings/errors
|
|
132
|
-
3. Check test results for failures and skipped tests
|
|
133
|
-
4. Check code signing logs for certificate/profile issues
|
|
134
|
-
5. Check Fastlane output for store upload errors
|
|
135
|
-
6. Note which pipeline step failed and its exit code
|
|
136
|
+
After triggering a build, poll status every 60 seconds. Check both iOS and Android independently. If one passes and one fails, report partial success and investigate. Verify artifacts (IPA/AAB) and store submission status after success. In logs, look for `ERROR`, `FAILURE`, `EXCEPTION`, `BUILD FAILED`, check Flutter analyze, test results, code signing, and Fastlane output.
|
|
136
137
|
|
|
137
138
|
### Output Format
|
|
138
139
|
|
|
@@ -142,18 +143,7 @@ PLATFORM: iOS | Android | Both
|
|
|
142
143
|
BUILD ID: [id]
|
|
143
144
|
STATUS: queued | building | testing | publishing | finished | failed
|
|
144
145
|
VERSION: [version]+[build_number]
|
|
145
|
-
|
|
146
|
-
For failures:
|
|
147
|
-
- Failed step: [step name]
|
|
148
|
-
- Error: [summary]
|
|
149
|
-
- Root cause: [analysis]
|
|
150
|
-
- Fix: [action taken or recommended]
|
|
151
|
-
|
|
152
|
-
For success:
|
|
153
|
-
- iOS: [App Store submission status]
|
|
154
|
-
- Android: [Google Play upload status]
|
|
155
|
-
- Artifacts: [list]
|
|
156
|
-
|
|
146
|
+
RESULT: [success details or failure analysis with root cause and fix]
|
|
157
147
|
RECOMMENDATION: [next action if needed]
|
|
158
148
|
```
|
|
159
149
|
|
|
@@ -383,7 +373,7 @@ Analyze Firestore usage patterns and optimize queries, indexes, and security rul
|
|
|
383
373
|
| `scripts/check_changed.sh` | Detects changed files for conditional uploads |
|
|
384
374
|
| `scripts/manage_version_ios.py` | iOS version auto-increment |
|
|
385
375
|
| `scripts/check_google_play.py` | Google Play readiness checker |
|
|
386
|
-
|
|
|
376
|
+
| `.mcp.json (codemagic)` | Codemagic MCP server config and API token |
|
|
387
377
|
| `fastlane/metadata/` | Store listing metadata (iOS + Android) |
|
|
388
378
|
| `fastlane/iap_config.json` | In-app purchase configuration |
|
|
389
379
|
| `web/deploy-cloudflare.mjs` | Cloudflare Pages deployment script |
|
package/src/install.mjs
CHANGED
|
@@ -110,12 +110,12 @@ function setupGitHubActions(codemagicToken) {
|
|
|
110
110
|
}
|
|
111
111
|
}
|
|
112
112
|
|
|
113
|
-
export async function runInstall(scope, isPostinstall = false) {
|
|
113
|
+
export async function runInstall(scope, isPostinstall = false, cliTokens = {}) {
|
|
114
114
|
checkClaudeCli();
|
|
115
115
|
|
|
116
116
|
console.log('Installing/updating Daemux Store Automator...');
|
|
117
117
|
|
|
118
|
-
const tokens = await promptForTokens();
|
|
118
|
+
const tokens = await promptForTokens(cliTokens);
|
|
119
119
|
|
|
120
120
|
const projectDir = process.cwd();
|
|
121
121
|
const servers = getMcpServers(tokens);
|
package/src/mcp-setup.mjs
CHANGED
|
@@ -32,6 +32,14 @@ export function getMcpServers(tokens) {
|
|
|
32
32
|
};
|
|
33
33
|
}
|
|
34
34
|
|
|
35
|
+
if (tokens.codemagicToken) {
|
|
36
|
+
servers.codemagic = {
|
|
37
|
+
command: 'npx',
|
|
38
|
+
args: ['-y', '@daemux/codemagic-mcp@latest'],
|
|
39
|
+
env: { CODEMAGIC_API_TOKEN: tokens.codemagicToken },
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
|
|
35
43
|
return servers;
|
|
36
44
|
}
|
|
37
45
|
|
|
@@ -75,7 +83,7 @@ export function removeMcpServers(projectDir) {
|
|
|
75
83
|
const data = readJson(mcpPath);
|
|
76
84
|
if (!data.mcpServers) return;
|
|
77
85
|
|
|
78
|
-
const toRemove = ['playwright', 'mobile-mcp', 'stitch', 'cloudflare'];
|
|
86
|
+
const toRemove = ['playwright', 'mobile-mcp', 'stitch', 'cloudflare', 'codemagic'];
|
|
79
87
|
for (const name of toRemove) {
|
|
80
88
|
delete data.mcpServers[name];
|
|
81
89
|
}
|
package/src/prompt.mjs
CHANGED
|
@@ -12,11 +12,32 @@ function ask(rl, question) {
|
|
|
12
12
|
});
|
|
13
13
|
}
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
function allTokensProvided(cliTokens) {
|
|
16
|
+
return (
|
|
17
|
+
cliTokens.stitchApiKey !== undefined &&
|
|
18
|
+
cliTokens.cloudflareToken !== undefined &&
|
|
19
|
+
cliTokens.cloudflareAccountId !== undefined &&
|
|
20
|
+
cliTokens.codemagicToken !== undefined
|
|
21
|
+
);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export async function promptForTokens(cliTokens = {}) {
|
|
25
|
+
const result = {
|
|
26
|
+
stitchApiKey: cliTokens.stitchApiKey ?? '',
|
|
27
|
+
cloudflareToken: cliTokens.cloudflareToken ?? '',
|
|
28
|
+
cloudflareAccountId: cliTokens.cloudflareAccountId ?? '',
|
|
29
|
+
codemagicToken: cliTokens.codemagicToken ?? '',
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
if (allTokensProvided(cliTokens)) {
|
|
33
|
+
console.log('All MCP tokens provided via CLI flags, skipping prompts.');
|
|
34
|
+
return result;
|
|
35
|
+
}
|
|
36
|
+
|
|
16
37
|
if (!isInteractive()) {
|
|
17
38
|
console.log('Non-interactive terminal detected, skipping token prompts.');
|
|
18
39
|
console.log('Run "npx store-automator" manually to configure MCP tokens.');
|
|
19
|
-
return
|
|
40
|
+
return result;
|
|
20
41
|
}
|
|
21
42
|
|
|
22
43
|
const rl = createInterface({
|
|
@@ -30,30 +51,35 @@ export async function promptForTokens() {
|
|
|
30
51
|
console.log('');
|
|
31
52
|
|
|
32
53
|
try {
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
54
|
+
if (cliTokens.stitchApiKey === undefined) {
|
|
55
|
+
result.stitchApiKey = await ask(
|
|
56
|
+
rl,
|
|
57
|
+
'Stitch MCP API Key (STITCH_API_KEY value): '
|
|
58
|
+
);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
if (cliTokens.cloudflareToken === undefined) {
|
|
62
|
+
result.cloudflareToken = await ask(
|
|
63
|
+
rl,
|
|
64
|
+
'Cloudflare API Token: '
|
|
65
|
+
);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
if (result.cloudflareToken && cliTokens.cloudflareAccountId === undefined) {
|
|
69
|
+
result.cloudflareAccountId = await ask(
|
|
46
70
|
rl,
|
|
47
71
|
'Cloudflare Account ID: '
|
|
48
72
|
);
|
|
49
73
|
}
|
|
50
74
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
75
|
+
if (cliTokens.codemagicToken === undefined) {
|
|
76
|
+
result.codemagicToken = await ask(
|
|
77
|
+
rl,
|
|
78
|
+
'Codemagic API Token (CM_API_TOKEN for CI/CD builds): '
|
|
79
|
+
);
|
|
80
|
+
}
|
|
55
81
|
|
|
56
|
-
return
|
|
82
|
+
return result;
|
|
57
83
|
} finally {
|
|
58
84
|
rl.close();
|
|
59
85
|
}
|
|
@@ -38,7 +38,7 @@ Prefer using the devops agent over direct Bash/SSH for structured operations.
|
|
|
38
38
|
## Configuration Files
|
|
39
39
|
|
|
40
40
|
### ci.config.yaml
|
|
41
|
-
Single source of truth: credentials, app identity, store settings, web domain, Codemagic CI/CD (app_id
|
|
41
|
+
Single source of truth: credentials, app identity, store settings, web domain, Codemagic CI/CD (app_id for GitHub Actions auto-trigger, workflow IDs). The Codemagic API token is managed by the codemagic MCP server in `.mcp.json`.
|
|
42
42
|
|
|
43
43
|
### fastlane/metadata/ Structure
|
|
44
44
|
All store listing texts are stored in fastlane directories and managed by the appstore-meta-creator agent:
|
|
@@ -57,10 +57,9 @@ web:
|
|
|
57
57
|
# === CODEMAGIC CI/CD ===
|
|
58
58
|
# Fill after creating app in Codemagic (https://codemagic.io/apps)
|
|
59
59
|
# Find app_id in your Codemagic dashboard URL: codemagic.io/app/{app_id}
|
|
60
|
-
#
|
|
60
|
+
# API token is stored in .mcp.json (codemagic MCP server, set during install)
|
|
61
61
|
codemagic:
|
|
62
62
|
app_id: ""
|
|
63
|
-
api_token: ""
|
|
64
63
|
workflows:
|
|
65
64
|
- ios-release
|
|
66
65
|
- android-release
|