@capgo/cli 8.22.1 → 8.23.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/dist/index.js +644 -642
- package/dist/package.json +6 -2
- package/dist/src/build/onboarding/android/android-rename.d.ts +54 -0
- package/dist/src/build/onboarding/android/app-verification-android.d.ts +44 -0
- package/dist/src/build/onboarding/android/flow.d.ts +26 -0
- package/dist/src/build/onboarding/android/oauth-google.d.ts +19 -0
- package/dist/src/build/onboarding/android/oauth-scopes.d.ts +9 -3
- package/dist/src/build/onboarding/android/reporting-api.d.ts +50 -0
- package/dist/src/build/onboarding/android/types.d.ts +9 -1
- package/dist/src/build/onboarding/mcp/engine.d.ts +1 -0
- package/dist/src/schemas/onboarding.d.ts +6 -0
- package/dist/src/sdk.js +300 -300
- package/package.json +6 -2
package/dist/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@capgo/cli",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "8.
|
|
4
|
+
"version": "8.23.1",
|
|
5
5
|
"description": "A CLI to upload to capgo servers",
|
|
6
6
|
"author": "Martin martin@capgo.app",
|
|
7
7
|
"license": "Apache 2.0",
|
|
@@ -72,6 +72,7 @@
|
|
|
72
72
|
"test:regex": "bun test/test-regex-validation.mjs",
|
|
73
73
|
"test:upload": "bun test/test-upload-validation.mjs",
|
|
74
74
|
"test:fail-on-incompatible": "bun test/test-fail-on-incompatible.mjs",
|
|
75
|
+
"test:native-dependencies": "bun test/test-native-dependencies.mjs",
|
|
75
76
|
"test:credentials": "bun test/test-credentials.mjs",
|
|
76
77
|
"test:asc-key-protocol": "bun test/test-asc-key-protocol.mjs",
|
|
77
78
|
"test:credentials-validation": "bun test/test-credentials-validation.mjs",
|
|
@@ -156,7 +157,7 @@
|
|
|
156
157
|
"test:ios-verify-app": "bun test/test-ios-verify-app.mjs",
|
|
157
158
|
"test:platform-flow-contract": "bun test/test-platform-flow-contract.mjs",
|
|
158
159
|
"test:tail-engine-shared": "bun test/test-tail-engine-shared.mjs",
|
|
159
|
-
"test": "bun run build && bun run test:helper-dce && bun run test:version-detection:setup && bun run test:bundle && bun run test:functional && bun run test:semver && bun run test:version-edge-cases && bun run test:regex && bun run test:upload && bun run test:fail-on-incompatible && bun run test:credentials && bun run test:credentials-validation && bun run test:android-service-account-validation && bun run test:build-zip-filter && bun run test:checksum && bun run test:build-needed && bun run test:ci-prompts && bun run test:ci-secrets && bun run test:android-onboarding-progress && bun run test:onboarding-telemetry && bun run test:v2-event-migration && bun run test:analytics && bun run test:analytics-error-category && bun run test:analytics-org-resolver && bun run test:supabase-perf && bun run test:preview-qr && bun run test:app-set-options && bun run test:mcp-analytics && bun run test:mcp-instructions && bun run test:mcp-live-update-onboarding && bun run test:mcp-stdout-guard && bun run test:mcp-platform-select && bun run test:mcp-explain-scopes && bun run test:mcp-oauth-reopen && bun run test:mcp-broker-oauth && bun run test:mcp-broker-session && bun run test:mcp-credentials-manage && bun run test:mcp-resume-prompt && bun run test:mcp-build-job && bun run test:mcp-build-tools && bun run test:app-created-source && bun run test:doctor-analytics && bun run test:posthog-exception && bun run test:build-platform-selection && bun run test:onboarding-recovery && bun run test:onboarding-progress && bun run test:onboarding-run-targets && bun run test:run-device-command && bun run test:init-app-conflict && bun run test:init-guardrails && bun run test:init-replay && bun run test:prompt-preferences && bun run test:esm-sdk && bun run test:mcp && bun run test:mcp-no-key-handshake && bun run test:auth-session && bun run test:version-detection && bun run test:platform-paths && bun run test:project-type-detection && bun run test:payload-split && bun run test:manifest-path-encoding && bun run test:macos-signing && bun run test:asc-key-protocol && bun run test:apple-api-import-helpers && bun run test:apple-api-verify-key && bun run test:bundle-id-detector && bun run test:apple-api-app-list && bun run test:app-verification && bun run test:pbxproj-parser && bun run test:ai-log-capture && bun run test:ai-analyze-flow && bun run test:cicd-failure-help && bun run test:ai-sse-parser && bun run test:ai-render-markdown && bun run test:ai-stream-markdown && bun run test:ai-onboarding-mode && bun run test:ai-fit && bun run test:platform-layout && bun run test:frame-fit && bun run test:onboarding-min-size && bun run test:min-size-gate && bun run test:shell-size-gate && bun run test:build-log-sanitize && bun run test:build-output-viewport && bun run test:diff-viewer-viewport && bun run test:build-complete-exit && bun run test:ai-analyze-stream && bun run test:support-mailto && bun run test:support-redact && bun run test:support-internal-log && bun run test:support-help-menu && bun run test:support-contact && bun run test:support-upload-prompt && bun run test:support-bundle-files && bun run test:self-update && bun run test:update-prompt && bun run test:apple-api-cert-create && bun run test:android-tail-engine && bun run test:android-tail-render && bun run test:android-tail-routing && bun run test:dev-gate-stripped && bun run test:frame-fit-ios-shared && bun run test:ios-confirm-app-id && bun run test:ios-create-new && bun run test:ios-e2e && bun run test:ios-flow-contract && bun run test:ios-import-discovery && bun run test:ios-import-export && bun run test:ios-import-pickers && bun run test:ios-import-recovery && bun run test:ios-recovery && bun run test:ios-resume && bun run test:ios-tail-handoff && bun run test:ios-tui-render && bun run test:p8-error && bun run test:ios-tui-routing && bun run test:ios-updater-sync-validation && bun run test:ios-verify-app && bun run test:platform-flow-contract && bun run test:tail-engine-shared && bun run test:prescan",
|
|
160
|
+
"test": "bun run build && bun run test:helper-dce && bun run test:version-detection:setup && bun run test:bundle && bun run test:functional && bun run test:semver && bun run test:version-edge-cases && bun run test:regex && bun run test:upload && bun run test:fail-on-incompatible && bun run test:native-dependencies && bun run test:credentials && bun run test:credentials-validation && bun run test:android-service-account-validation && bun run test:build-zip-filter && bun run test:checksum && bun run test:build-needed && bun run test:ci-prompts && bun run test:ci-secrets && bun run test:android-onboarding-progress && bun run test:onboarding-telemetry && bun run test:v2-event-migration && bun run test:analytics && bun run test:analytics-error-category && bun run test:analytics-org-resolver && bun run test:supabase-perf && bun run test:preview-qr && bun run test:app-set-options && bun run test:mcp-analytics && bun run test:mcp-instructions && bun run test:mcp-live-update-onboarding && bun run test:mcp-stdout-guard && bun run test:mcp-platform-select && bun run test:mcp-explain-scopes && bun run test:mcp-oauth-reopen && bun run test:mcp-broker-oauth && bun run test:mcp-broker-session && bun run test:mcp-credentials-manage && bun run test:mcp-resume-prompt && bun run test:mcp-build-job && bun run test:mcp-build-tools && bun run test:app-created-source && bun run test:doctor-analytics && bun run test:posthog-exception && bun run test:build-platform-selection && bun run test:onboarding-recovery && bun run test:onboarding-progress && bun run test:onboarding-run-targets && bun run test:run-device-command && bun run test:init-app-conflict && bun run test:init-guardrails && bun run test:init-replay && bun run test:prompt-preferences && bun run test:esm-sdk && bun run test:mcp && bun run test:mcp-no-key-handshake && bun run test:auth-session && bun run test:version-detection && bun run test:platform-paths && bun run test:project-type-detection && bun run test:payload-split && bun run test:manifest-path-encoding && bun run test:macos-signing && bun run test:asc-key-protocol && bun run test:apple-api-import-helpers && bun run test:apple-api-verify-key && bun run test:bundle-id-detector && bun run test:apple-api-app-list && bun run test:app-verification && bun run test:pbxproj-parser && bun run test:ai-log-capture && bun run test:ai-analyze-flow && bun run test:cicd-failure-help && bun run test:ai-sse-parser && bun run test:ai-render-markdown && bun run test:ai-stream-markdown && bun run test:ai-onboarding-mode && bun run test:ai-fit && bun run test:platform-layout && bun run test:frame-fit && bun run test:onboarding-min-size && bun run test:min-size-gate && bun run test:shell-size-gate && bun run test:build-log-sanitize && bun run test:build-output-viewport && bun run test:diff-viewer-viewport && bun run test:build-complete-exit && bun run test:ai-analyze-stream && bun run test:support-mailto && bun run test:support-redact && bun run test:support-internal-log && bun run test:support-help-menu && bun run test:support-contact && bun run test:support-upload-prompt && bun run test:support-bundle-files && bun run test:self-update && bun run test:update-prompt && bun run test:apple-api-cert-create && bun run test:android-tail-engine && bun run test:android-tail-render && bun run test:android-tail-routing && bun run test:dev-gate-stripped && bun run test:frame-fit-ios-shared && bun run test:ios-confirm-app-id && bun run test:ios-create-new && bun run test:ios-e2e && bun run test:ios-flow-contract && bun run test:ios-import-discovery && bun run test:ios-import-export && bun run test:ios-import-pickers && bun run test:ios-import-recovery && bun run test:ios-recovery && bun run test:ios-resume && bun run test:ios-tail-handoff && bun run test:ios-tui-render && bun run test:p8-error && bun run test:ios-tui-routing && bun run test:ios-updater-sync-validation && bun run test:ios-verify-app && bun run test:platform-flow-contract && bun run test:tail-engine-shared && bun run test:prescan && bun run test:android-reporting-api && bun run test:android-app-verification && bun run test:android-rename",
|
|
160
161
|
"test:build-platform-selection": "bun test/test-build-platform-selection.mjs",
|
|
161
162
|
"test:ai-log-capture": "bun test/test-ai-log-capture.mjs",
|
|
162
163
|
"test:ai-analyze-flow": "bun test/test-ai-analyze-flow.mjs",
|
|
@@ -184,6 +185,9 @@
|
|
|
184
185
|
"test:support-upload-prompt": "bun test/test-support-upload-prompt.mjs",
|
|
185
186
|
"test:support-bundle-files": "bun test/test-support-bundle-files.mjs",
|
|
186
187
|
"test:mcp-live-update-onboarding": "bun test/test-mcp-live-update-onboarding.mjs",
|
|
188
|
+
"test:android-reporting-api": "bun test/test-android-reporting-api.mjs",
|
|
189
|
+
"test:android-app-verification": "bun test/test-android-app-verification.mjs",
|
|
190
|
+
"test:android-rename": "bun test/test-android-rename.mjs",
|
|
187
191
|
"test:app-set-options": "bun test/test-app-set-options.mjs"
|
|
188
192
|
},
|
|
189
193
|
"dependencies": {
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pinned `@trapezedev/project` version installed on demand into the temp rename
|
|
3
|
+
* workspace. Trapeze is NOT bundled with the CLI (keeps it lean) — it's only
|
|
4
|
+
* installed when the user explicitly opts into the rename. Pinned so the rename
|
|
5
|
+
* behavior is reproducible.
|
|
6
|
+
*/
|
|
7
|
+
export declare const TRAPEZE_PROJECT_VERSION = "7.1.4";
|
|
8
|
+
export interface RenameWorkspaceFiles {
|
|
9
|
+
/** Contents of the temp `package.json` (`type: module` + pinned Trapeze). */
|
|
10
|
+
packageJson: string;
|
|
11
|
+
/** Contents of the `rename.mjs` script run as `node rename.mjs <appId>`. */
|
|
12
|
+
renameMjs: string;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Build the two files written into the temp rename workspace.
|
|
16
|
+
*
|
|
17
|
+
* The `rename.mjs` script runs the proven 3-call Trapeze sequence — ALWAYS all
|
|
18
|
+
* three setters (`setPackageName` + `setApplicationId` + `setNamespace`).
|
|
19
|
+
* Skipping `namespace` is not an option: AGP 8 requires it, and a package move
|
|
20
|
+
* with a stale namespace breaks `R`/`BuildConfig` imports and fails the build.
|
|
21
|
+
* The `appId` is read from `process.argv[2]` so the caller passes the target
|
|
22
|
+
* package as a CLI argument rather than templating it into the script.
|
|
23
|
+
*
|
|
24
|
+
* `pkg` is accepted for symmetry / future validation but is intentionally NOT
|
|
25
|
+
* interpolated into the script — the appId always flows in via argv at runtime,
|
|
26
|
+
* which avoids any string-injection of an attacker-controlled package into the
|
|
27
|
+
* generated JS.
|
|
28
|
+
*
|
|
29
|
+
* `androidDir` is the resolved native directory (from capacitor.config; it may be
|
|
30
|
+
* a non-default path like `apps/mobile/platforms/android-native`). It is baked
|
|
31
|
+
* into the MobileProject config JSON-escaped so the rename targets the CONFIGURED
|
|
32
|
+
* native project, never a hardcoded `./android` (which could mutate a stale tree).
|
|
33
|
+
*/
|
|
34
|
+
export declare function buildRenameWorkspaceFiles(pkg: string, androidDir: string): RenameWorkspaceFiles;
|
|
35
|
+
/** Whether Android Studio is holding the project's native files open. */
|
|
36
|
+
export type AndroidStudioState = 'running' | 'not-running' | 'unknown';
|
|
37
|
+
/**
|
|
38
|
+
* Pure predicate for the close-Android-Studio gate. Editing native files while
|
|
39
|
+
* Studio holds them open risks a half-written project / Studio clobbering the
|
|
40
|
+
* change.
|
|
41
|
+
*
|
|
42
|
+
* Only macOS can be determined here: `pgrep -f "Android Studio"` is the source
|
|
43
|
+
* of `pgrepOutput`, so a non-empty (trimmed) result means it's running and an
|
|
44
|
+
* empty one means it's closed. On any other platform we can't reliably probe,
|
|
45
|
+
* so the caller falls back to a one-time confirm → `unknown`.
|
|
46
|
+
*/
|
|
47
|
+
export declare function isAndroidStudioRunning(platform: string, pgrepOutput: string): AndroidStudioState;
|
|
48
|
+
/**
|
|
49
|
+
* Verify the rename landed: re-read Gradle ids (via `findAndroidApplicationIds`,
|
|
50
|
+
* which returns `string[]`) and confirm the list now contains the target
|
|
51
|
+
* package. Returns `false` so the caller surfaces output + a manual fallback
|
|
52
|
+
* instead of claiming a false success.
|
|
53
|
+
*/
|
|
54
|
+
export declare function verifyRenamed(gradleIds: string[], target: string): boolean;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/** Minimal shape of a Play Store app needed for reconciliation. */
|
|
2
|
+
export interface PlayAppLike {
|
|
3
|
+
packageName: string;
|
|
4
|
+
displayName: string;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* Reconcile outcome for the Android package-select step.
|
|
8
|
+
*
|
|
9
|
+
* - `exact-match` — a Play app's `packageName` == a single clean Gradle id.
|
|
10
|
+
* Auto-confirm, no picker. Carries the matched package.
|
|
11
|
+
* - `wrong-build-id` — apps exist but the build id matches none → Path A picker.
|
|
12
|
+
* - `no-app` — no Play apps at all → Path B (create the app).
|
|
13
|
+
* - `multi-gradle` — several Gradle flavors and no clean single match → force
|
|
14
|
+
* the picker so the user disambiguates.
|
|
15
|
+
*/
|
|
16
|
+
export type AndroidReconcileResult = {
|
|
17
|
+
kind: 'exact-match';
|
|
18
|
+
packageName: string;
|
|
19
|
+
} | {
|
|
20
|
+
kind: 'wrong-build-id';
|
|
21
|
+
} | {
|
|
22
|
+
kind: 'no-app';
|
|
23
|
+
} | {
|
|
24
|
+
kind: 'multi-gradle';
|
|
25
|
+
};
|
|
26
|
+
export interface ReconcileAndroidAppInput {
|
|
27
|
+
/** Every distinct `applicationId` found in the project's Gradle files (≥0). */
|
|
28
|
+
gradleIds: string[];
|
|
29
|
+
/** Apps that actually exist in the user's Play Console. */
|
|
30
|
+
apps: PlayAppLike[];
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Pure reconciliation of the Android app-existence invariant.
|
|
34
|
+
*
|
|
35
|
+
* The common Capacitor case is a single Gradle id, which defers entirely to the
|
|
36
|
+
* shared iOS classifier (`packageName` ↦ `bundleId`). Android has no
|
|
37
|
+
* Developer-portal registration split, so both iOS `no-app-*` results collapse
|
|
38
|
+
* to a single `no-app` route.
|
|
39
|
+
*
|
|
40
|
+
* Multiple Gradle ids are handled here: exactly one matching a Play app is
|
|
41
|
+
* still a clean single match (`exact-match`); zero apps is `no-app`; anything
|
|
42
|
+
* else forces the picker (`multi-gradle`).
|
|
43
|
+
*/
|
|
44
|
+
export declare function reconcileAndroidApp(input: ReconcileAndroidAppInput): AndroidReconcileResult;
|
|
@@ -46,6 +46,18 @@ export interface AndroidStepView {
|
|
|
46
46
|
export interface AndroidStepCtx {
|
|
47
47
|
appId: string;
|
|
48
48
|
detectedPackageIds?: string[];
|
|
49
|
+
/**
|
|
50
|
+
* android-app-verify transient: the user's real Play Store apps (apps:search)
|
|
51
|
+
* + the reconcile outcome for the chosen package. Set in the effect's
|
|
52
|
+
* transient ONLY when the chosen package is not an exact match (and the
|
|
53
|
+
* fetch succeeded), so the view renders the create-app / re-check gate.
|
|
54
|
+
* Absent → the step is still auto (run the fetch) or already advanced.
|
|
55
|
+
*/
|
|
56
|
+
playVerifyApps?: {
|
|
57
|
+
packageName: string;
|
|
58
|
+
displayName: string;
|
|
59
|
+
}[];
|
|
60
|
+
playVerifyOutcome?: 'no-app' | 'wrong-build-id' | 'multi-gradle';
|
|
49
61
|
gcpProjects?: {
|
|
50
62
|
projectId: string;
|
|
51
63
|
name: string;
|
|
@@ -209,6 +221,9 @@ export type AndroidInput = {
|
|
|
209
221
|
packageName: string;
|
|
210
222
|
source: 'gradle' | 'capacitor-config' | 'user-input';
|
|
211
223
|
serviceAccountMethod: 'generate' | 'existing';
|
|
224
|
+
} | {
|
|
225
|
+
step: 'android-app-verify';
|
|
226
|
+
verifyAction: 'open' | 'recheck' | 'cancel' | 'proceed';
|
|
212
227
|
} | {
|
|
213
228
|
step: 'ci-secrets-setup';
|
|
214
229
|
value: 'retry' | 'skip';
|
|
@@ -320,6 +335,17 @@ export interface AndroidEffectDeps {
|
|
|
320
335
|
* Mirrors gcp-api.ts: listProjects(accessToken).
|
|
321
336
|
*/
|
|
322
337
|
listProjects: (accessToken: string) => Promise<GcpProject[]>;
|
|
338
|
+
/**
|
|
339
|
+
* List the user's Play Store apps via the Play Developer Reporting API
|
|
340
|
+
* (apps:search). OPTIONAL — present only when the optional
|
|
341
|
+
* playdeveloperreporting scope was granted; absent → android-app-verify
|
|
342
|
+
* degrades (advances without verifying, never blocks). Mirrors
|
|
343
|
+
* reporting-api.ts: listPlayApps(accessToken).
|
|
344
|
+
*/
|
|
345
|
+
listPlayApps?: (accessToken: string) => Promise<{
|
|
346
|
+
packageName: string;
|
|
347
|
+
displayName: string;
|
|
348
|
+
}[]>;
|
|
323
349
|
/**
|
|
324
350
|
* Create a GCP project and wait for the operation to finish.
|
|
325
351
|
* Mirrors gcp-api.ts: createProject(accessToken, projectId, displayName).
|
|
@@ -8,6 +8,13 @@ export interface GoogleOAuthConfig {
|
|
|
8
8
|
*/
|
|
9
9
|
clientSecret?: string;
|
|
10
10
|
scopes: readonly string[];
|
|
11
|
+
/**
|
|
12
|
+
* Subset of `scopes` whose absence must FAIL sign-in (throw
|
|
13
|
+
* MissingScopesError). Scopes in `scopes` but NOT here are OPTIONAL — the user
|
|
14
|
+
* may decline them on the consent screen and sign-in still succeeds; the
|
|
15
|
+
* caller is responsible for degrading gracefully. Defaults to all `scopes`.
|
|
16
|
+
*/
|
|
17
|
+
requiredScopes?: readonly string[];
|
|
11
18
|
/** Extra params to include on the auth URL (e.g. `login_hint`, `prompt`). */
|
|
12
19
|
extraAuthParams?: Record<string, string>;
|
|
13
20
|
}
|
|
@@ -111,6 +118,18 @@ export declare class MissingScopesError extends Error {
|
|
|
111
118
|
* order in `requestedScopes` is not preserved. Empty strings are filtered out.
|
|
112
119
|
*/
|
|
113
120
|
export declare function findMissingScopes(grantedScope: string, requestedScopes: readonly string[]): string[];
|
|
121
|
+
export interface MissingScopeSplit {
|
|
122
|
+
/** Required scopes the user didn't grant — sign-in must fail with a retry. */
|
|
123
|
+
missingRequired: string[];
|
|
124
|
+
/** Optional scopes the user declined — proceed, but tell them what they lose. */
|
|
125
|
+
skippedOptional: string[];
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Split the requested-but-not-granted scopes into the required ones (block
|
|
129
|
+
* sign-in → MissingScopesError) and the optional ones (sign-in proceeds; the
|
|
130
|
+
* success page + caller warn about the degraded behavior).
|
|
131
|
+
*/
|
|
132
|
+
export declare function splitMissingScopes(grantedScope: string, scopes: readonly string[], requiredScopes: readonly string[]): MissingScopeSplit;
|
|
114
133
|
export interface LoopbackCallbackResult {
|
|
115
134
|
/** Authorization code Google returned in the query string. */
|
|
116
135
|
code: string;
|
|
@@ -1,4 +1,10 @@
|
|
|
1
1
|
/** OAuth scopes for Capgo Android onboarding — androidpublisher (Play) plus
|
|
2
|
-
* cloud-platform (create GCP projects / service accounts / keys)
|
|
3
|
-
*
|
|
4
|
-
|
|
2
|
+
* cloud-platform (create GCP projects / service accounts / keys), and the
|
|
3
|
+
* OPTIONAL playdeveloperreporting scope used by the app-existence verification
|
|
4
|
+
* step (apps:search). Shared by the Ink wizard and the MCP bridge so the two
|
|
5
|
+
* drivers can never drift. */
|
|
6
|
+
export declare const OAUTH_SCOPES_FOR_ONBOARDING: readonly ["openid", "https://www.googleapis.com/auth/userinfo.email", "https://www.googleapis.com/auth/androidpublisher", "https://www.googleapis.com/auth/cloud-platform", "https://www.googleapis.com/auth/playdeveloperreporting"];
|
|
7
|
+
/** The subset of {@link OAUTH_SCOPES_FOR_ONBOARDING} whose absence must FAIL
|
|
8
|
+
* sign-in. Excludes the optional playdeveloperreporting scope so a user who
|
|
9
|
+
* declines app-listing still completes onboarding (graceful degradation). */
|
|
10
|
+
export declare const OAUTH_REQUIRED_SCOPES: readonly ["openid", "https://www.googleapis.com/auth/userinfo.email", "https://www.googleapis.com/auth/androidpublisher", "https://www.googleapis.com/auth/cloud-platform"];
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A Play Store app record as returned by `apps:search`. Used by the Android
|
|
3
|
+
* app-verification step to check whether an app exists whose `packageName`
|
|
4
|
+
* matches the project's Gradle `applicationId`.
|
|
5
|
+
*/
|
|
6
|
+
export interface PlayApp {
|
|
7
|
+
packageName: string;
|
|
8
|
+
displayName: string;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Parse an `apps:search` response into {@link PlayApp} records. Tolerant of a
|
|
12
|
+
* missing `apps` array and of individual apps missing `displayName` — Google
|
|
13
|
+
* omits fields rather than nulling them, and a malformed page must never throw
|
|
14
|
+
* into the wizard (the whole feature degrades gracefully).
|
|
15
|
+
*
|
|
16
|
+
* Entries missing `packageName` are DROPPED: the package is the join key for
|
|
17
|
+
* reconciliation, and letting an empty one through could spuriously
|
|
18
|
+
* "exact-match" a project whose Gradle parse found no applicationId. The API
|
|
19
|
+
* documents `packageName` as always present, so this only guards malformed
|
|
20
|
+
* pages.
|
|
21
|
+
*/
|
|
22
|
+
export declare function parseAppsSearchResponse(json: any): PlayApp[];
|
|
23
|
+
/**
|
|
24
|
+
* Carries the HTTP status alongside the message so callers can distinguish a
|
|
25
|
+
* 403 (scope not granted / Reporting API disabled → graceful degrade to the
|
|
26
|
+
* plain Gradle picker) from other failures.
|
|
27
|
+
*/
|
|
28
|
+
export declare class ReportingApiHttpError extends Error {
|
|
29
|
+
readonly status: number;
|
|
30
|
+
constructor(status: number, message: string);
|
|
31
|
+
}
|
|
32
|
+
/** Injectable fetch — defaults to the global `fetch`, overridable in tests. */
|
|
33
|
+
export type FetchImpl = typeof fetch;
|
|
34
|
+
export interface ListPlayAppsOptions {
|
|
35
|
+
/**
|
|
36
|
+
* Override the global `fetch`. Tests inject a stub returning a Response-like
|
|
37
|
+
* object; production omits this and uses `globalThis.fetch`.
|
|
38
|
+
*/
|
|
39
|
+
fetchImpl?: FetchImpl;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* List every Play Store app accessible to the signed-in user, following
|
|
43
|
+
* pagination. Authenticates with the supplied user OAuth access token (must
|
|
44
|
+
* carry the `playdeveloperreporting` scope).
|
|
45
|
+
*
|
|
46
|
+
* `GET …/v1beta1/apps:search?pageSize=1000`, following `nextPageToken` up to
|
|
47
|
+
* {@link MAX_LIST_PAGES}. Throws {@link ReportingApiHttpError} on a non-OK
|
|
48
|
+
* response so callers can branch on `.status` (e.g. 403 → degrade).
|
|
49
|
+
*/
|
|
50
|
+
export declare function listPlayApps(accessToken: string, opts?: ListPlayAppsOptions): Promise<PlayApp[]>;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { TailProgress } from '../tail-types.js';
|
|
2
|
-
export type AndroidOnboardingStep = 'welcome' | 'resume-prompt' | 'credentials-exist' | 'backing-up' | 'no-platform' | 'keystore-method-select' | 'keystore-explainer' | 'keystore-existing-path' | 'keystore-existing-picker' | 'keystore-existing-store-password' | 'keystore-existing-detecting-alias' | 'keystore-existing-alias-select' | 'keystore-existing-alias' | 'keystore-existing-key-password' | 'keystore-new-alias' | 'keystore-new-password-method' | 'keystore-new-store-password' | 'keystore-new-key-password' | 'keystore-new-cn' | 'keystore-generating' | 'service-account-method-select' | 'sa-json-existing-path' | 'sa-json-existing-picker' | 'sa-json-validating' | 'sa-json-validation-failed' | 'google-sign-in' | 'google-sign-in-running' | 'play-developer-id-input' | 'gcp-projects-loading' | 'gcp-projects-select' | 'gcp-project-create-name' | 'android-package-select' | 'gcp-setup-running' | 'saving-credentials' | 'detecting-ci-secrets' | 'ci-secrets-setup' | 'ci-secrets-target-select' | 'ask-ci-secrets' | 'checking-ci-secrets' | 'confirm-ci-secret-overwrite' | 'uploading-ci-secrets' | 'ci-secrets-failed' | 'ask-github-actions-setup' | 'confirm-secrets-push' | 'ask-export-env' | 'exporting-env' | 'confirm-env-export-overwrite' | 'overwrite-and-export-env' | 'pick-package-manager' | 'pick-build-script' | 'pick-build-script-custom' | 'preview-workflow-file' | 'view-workflow-diff' | 'writing-workflow-file' | 'ask-build' | 'requesting-build' | 'ai-analysis-prompt' | 'ai-analysis-running' | 'ai-analysis-result' | 'ai-analysis-result-scroll' | 'build-complete' | 'error' | 'support-confirm' | 'support-log-view' | 'support-uploading';
|
|
2
|
+
export type AndroidOnboardingStep = 'welcome' | 'resume-prompt' | 'credentials-exist' | 'backing-up' | 'no-platform' | 'keystore-method-select' | 'keystore-explainer' | 'keystore-existing-path' | 'keystore-existing-picker' | 'keystore-existing-store-password' | 'keystore-existing-detecting-alias' | 'keystore-existing-alias-select' | 'keystore-existing-alias' | 'keystore-existing-key-password' | 'keystore-new-alias' | 'keystore-new-password-method' | 'keystore-new-store-password' | 'keystore-new-key-password' | 'keystore-new-cn' | 'keystore-generating' | 'service-account-method-select' | 'sa-json-existing-path' | 'sa-json-existing-picker' | 'sa-json-validating' | 'sa-json-validation-failed' | 'google-sign-in' | 'google-sign-in-running' | 'play-developer-id-input' | 'gcp-projects-loading' | 'gcp-projects-select' | 'gcp-project-create-name' | 'android-package-select' | 'android-app-verify' | 'gcp-setup-running' | 'saving-credentials' | 'detecting-ci-secrets' | 'ci-secrets-setup' | 'ci-secrets-target-select' | 'ask-ci-secrets' | 'checking-ci-secrets' | 'confirm-ci-secret-overwrite' | 'uploading-ci-secrets' | 'ci-secrets-failed' | 'ask-github-actions-setup' | 'confirm-secrets-push' | 'ask-export-env' | 'exporting-env' | 'confirm-env-export-overwrite' | 'overwrite-and-export-env' | 'pick-package-manager' | 'pick-build-script' | 'pick-build-script-custom' | 'preview-workflow-file' | 'view-workflow-diff' | 'writing-workflow-file' | 'ask-build' | 'requesting-build' | 'ai-analysis-prompt' | 'ai-analysis-running' | 'ai-analysis-result' | 'ai-analysis-result-scroll' | 'build-complete' | 'error' | 'support-confirm' | 'support-log-view' | 'support-uploading';
|
|
3
3
|
export type AndroidOnboardingErrorCategory = 'keystore_invalid' | 'google_oauth_failed' | 'play_account_id_invalid' | 'sa_json_shape_invalid' | 'sa_json_token_rejected' | 'sa_json_no_app_access' | 'sa_json_network_error' | 'unknown';
|
|
4
4
|
export type KeystoreMethod = 'existing' | 'generate';
|
|
5
5
|
export type ServiceAccountMethod = 'existing' | 'generate';
|
|
@@ -75,6 +75,14 @@ export interface AndroidOnboardingProgress extends TailProgress {
|
|
|
75
75
|
playAccountChosen?: PlayDeveloperAccountChoice;
|
|
76
76
|
gcpProjectChosen?: GcpProjectChoice;
|
|
77
77
|
androidPackageChosen?: AndroidPackageChoice;
|
|
78
|
+
/** Set once the chosen package was verified to exist in the user's Play
|
|
79
|
+
* Console (apps:search exact-match), or the user explicitly proceeded past
|
|
80
|
+
* a degraded/un-verifiable check. Gates `gcp-setup-running` so the
|
|
81
|
+
* per-package SA invite never 400s on a non-existent package. */
|
|
82
|
+
playAppVerified?: {
|
|
83
|
+
packageName: string;
|
|
84
|
+
verified: boolean;
|
|
85
|
+
};
|
|
78
86
|
serviceAccountProvisioned?: ServiceAccountProvisioned;
|
|
79
87
|
playInviteProvisioned?: PlayInviteProvisioned;
|
|
80
88
|
/** Set once `saving-credentials` wrote credentials.json. Gates tail entry. */
|
|
@@ -30,6 +30,7 @@ interface OnboardingInput {
|
|
|
30
30
|
gcpProjectId?: string;
|
|
31
31
|
gcpProjectName?: string;
|
|
32
32
|
androidPackage?: string;
|
|
33
|
+
androidVerifyAction?: 'open' | 'recheck' | 'cancel' | 'proceed';
|
|
33
34
|
saMethodChoice?: 'retry' | 'save-anyway' | 'oauth';
|
|
34
35
|
/** Set true at google-sign-in to (re)open the browser for a fresh OAuth — recovery when the browser didn't open, was closed, or the sign-in stalled. */
|
|
35
36
|
reopenSignIn?: boolean;
|
|
@@ -17,6 +17,12 @@ export declare const onboardingNextStepSchema: z.ZodObject<{
|
|
|
17
17
|
gcpProjectId: z.ZodOptional<z.ZodString>;
|
|
18
18
|
gcpProjectName: z.ZodOptional<z.ZodString>;
|
|
19
19
|
androidPackage: z.ZodOptional<z.ZodString>;
|
|
20
|
+
androidVerifyAction: z.ZodOptional<z.ZodEnum<{
|
|
21
|
+
open: "open";
|
|
22
|
+
proceed: "proceed";
|
|
23
|
+
cancel: "cancel";
|
|
24
|
+
recheck: "recheck";
|
|
25
|
+
}>>;
|
|
20
26
|
saMethodChoice: z.ZodOptional<z.ZodEnum<{
|
|
21
27
|
retry: "retry";
|
|
22
28
|
oauth: "oauth";
|