@gpc-cli/cli 0.9.64 → 0.9.66

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 (30) hide show
  1. package/README.md +13 -12
  2. package/dist/bin.js +2 -2
  3. package/dist/{changelog-EHQYZP22.js → changelog-STYBBYDC.js} +8 -2
  4. package/dist/changelog-STYBBYDC.js.map +1 -0
  5. package/dist/{chunk-I3SFXLIY.js → chunk-IUG4225Q.js} +11 -11
  6. package/dist/{config-SK7BOURM.js → config-DDZMNYOB.js} +2 -2
  7. package/dist/{docs-WVJCDX5X.js → docs-OU6LSSJD.js} +16 -7
  8. package/dist/{docs-WVJCDX5X.js.map → docs-OU6LSSJD.js.map} +1 -1
  9. package/dist/{doctor-FSUI44DD.js → doctor-QRHXY3FC.js} +181 -10
  10. package/dist/doctor-QRHXY3FC.js.map +1 -0
  11. package/dist/{feedback-PDQU5E6S.js → feedback-C2BA7CK6.js} +2 -2
  12. package/dist/generated/docs-bundle.json +1 -1
  13. package/dist/index.js +1 -1
  14. package/dist/{preflight-KIWZPFTX.js → preflight-BL67VGUX.js} +54 -1
  15. package/dist/preflight-BL67VGUX.js.map +1 -0
  16. package/dist/{update-E4VGHQUR.js → update-GEH352BE.js} +2 -2
  17. package/dist/verify-O2PSBTIC.js +330 -0
  18. package/dist/verify-O2PSBTIC.js.map +1 -0
  19. package/dist/{version-HXUIOHCL.js → version-2RUEWMPK.js} +2 -2
  20. package/package.json +4 -4
  21. package/dist/changelog-EHQYZP22.js.map +0 -1
  22. package/dist/doctor-FSUI44DD.js.map +0 -1
  23. package/dist/preflight-KIWZPFTX.js.map +0 -1
  24. package/dist/verify-H4ZUVHMZ.js +0 -98
  25. package/dist/verify-H4ZUVHMZ.js.map +0 -1
  26. /package/dist/{chunk-I3SFXLIY.js.map → chunk-IUG4225Q.js.map} +0 -0
  27. /package/dist/{config-SK7BOURM.js.map → config-DDZMNYOB.js.map} +0 -0
  28. /package/dist/{feedback-PDQU5E6S.js.map → feedback-C2BA7CK6.js.map} +0 -0
  29. /package/dist/{update-E4VGHQUR.js.map → update-GEH352BE.js.map} +0 -0
  30. /package/dist/{version-HXUIOHCL.js.map → version-2RUEWMPK.js.map} +0 -0
package/dist/index.js CHANGED
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  createProgram,
4
4
  handleCliError
5
- } from "./chunk-I3SFXLIY.js";
5
+ } from "./chunk-IUG4225Q.js";
6
6
  export {
7
7
  createProgram,
8
8
  handleCliError
@@ -59,6 +59,59 @@ function registerPreflightCommand(program) {
59
59
  scanners: "secrets,billing,privacy"
60
60
  });
61
61
  });
62
+ cmd.command("signing").description("Check signing key consistency across releases (requires auth)").action(async (_options, subcmd) => {
63
+ const parentOpts = subcmd.parent?.parent?.opts() ?? {};
64
+ const jsonMode = !!(parentOpts["json"] || parentOpts["output"] === "json");
65
+ const config = await loadConfig();
66
+ const packageName = parentOpts["app"] ?? config.app;
67
+ if (!packageName) {
68
+ throw new GpcError(
69
+ "No app configured",
70
+ "MISSING_APP",
71
+ 2,
72
+ "Set a default app with 'gpc config set app <package>' or use --app"
73
+ );
74
+ }
75
+ const { resolveAuth } = await import("@gpc-cli/auth");
76
+ const client = await resolveAuth({
77
+ serviceAccountPath: config.auth?.serviceAccount
78
+ });
79
+ const accessToken = await client.getAccessToken();
80
+ const { checkSigningConsistency } = await import("@gpc-cli/core");
81
+ const result = await checkSigningConsistency(accessToken, packageName);
82
+ if (jsonMode) {
83
+ console.log(JSON.stringify(result, null, 2));
84
+ } else {
85
+ console.log("");
86
+ console.log(bold("Signing Key Consistency"));
87
+ console.log("");
88
+ if (result.firstRelease) {
89
+ console.log(
90
+ ` ${dim("\u2139")} First release (v${result.currentVersionCode}): ${result.currentFingerprint}`
91
+ );
92
+ console.log(` ${dim("Nothing to compare against yet.")}`);
93
+ } else if (result.consistent) {
94
+ console.log(
95
+ ` ${green("\u2713")} Consistent: v${result.previousVersionCode} \u2192 v${result.currentVersionCode}`
96
+ );
97
+ console.log(` ${dim("Fingerprint:")} ${result.currentFingerprint}`);
98
+ } else {
99
+ console.log(
100
+ ` ${red("\u2717")} Signing key changed between v${result.previousVersionCode} and v${result.currentVersionCode}`
101
+ );
102
+ console.log(` ${dim("Previous:")} ${result.previousFingerprint}`);
103
+ console.log(` ${dim("Current:")} ${result.currentFingerprint}`);
104
+ console.log("");
105
+ console.log(
106
+ ` ${yellow("\u26A0")} If intentional, register the new key in Play Console before September 2026.`
107
+ );
108
+ }
109
+ console.log("");
110
+ }
111
+ if (!result.consistent) {
112
+ process.exitCode = 6;
113
+ }
114
+ });
62
115
  }
63
116
  async function runPreflightAction(program, file, options) {
64
117
  if (!file && !options["metadata"] && !options["source"]) {
@@ -147,4 +200,4 @@ async function runPreflightAction(program, file, options) {
147
200
  export {
148
201
  registerPreflightCommand
149
202
  };
150
- //# sourceMappingURL=preflight-KIWZPFTX.js.map
203
+ //# sourceMappingURL=preflight-BL67VGUX.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/commands/preflight.ts"],"sourcesContent":["// Named exports only. No default export.\n\nimport type { Command } from \"commander\";\nimport { runPreflight, getAllScannerNames, formatOutput, GpcError } from \"@gpc-cli/core\";\nimport type { FindingSeverity } from \"@gpc-cli/core\";\nimport { getOutputFormat } from \"../format.js\";\nimport { loadConfig } from \"@gpc-cli/config\";\nimport { green, red, yellow, dim, bold } from \"../colors.js\";\n\nconst SEVERITY_ICONS: Record<FindingSeverity, string> = {\n critical: \"✗\",\n error: \"✗\",\n warning: \"⚠\",\n info: \"ℹ\",\n};\n\nfunction severityColor(severity: FindingSeverity, text: string): string {\n switch (severity) {\n case \"critical\":\n return bold(red(text));\n case \"error\":\n return red(text);\n case \"warning\":\n return yellow(text);\n case \"info\":\n return dim(text);\n }\n}\n\nexport function registerPreflightCommand(program: Command): void {\n const cmd = program\n .command(\"preflight [file]\")\n .description(\"Pre-submission compliance scanner for AAB files (offline)\")\n .option(\n \"--fail-on <severity>\",\n \"Fail if any finding meets or exceeds severity: critical, error, warning, info\",\n \"error\",\n )\n .option(\"--scanners <names>\", \"Comma-separated scanner names to run (default: all)\")\n .option(\"--metadata <dir>\", \"Path to metadata directory (Fastlane format) for listing checks\")\n .option(\"--source <dir>\", \"Path to source directory for code scanning\")\n .option(\"--config <path>\", \"Path to .preflightrc.json config file\")\n .action(async (file: string | undefined, options) => {\n await runPreflightAction(program, file, options);\n });\n\n // Subcommand: preflight manifest\n cmd\n .command(\"manifest <file>\")\n .description(\"Run manifest scanner only\")\n .option(\"--fail-on <severity>\", \"Fail threshold\", \"error\")\n .action(async (file: string, options) => {\n await runPreflightAction(program, file, { ...options, scanners: \"manifest\" });\n });\n\n // Subcommand: preflight permissions\n cmd\n .command(\"permissions <file>\")\n .description(\"Run permissions scanner only\")\n .option(\"--fail-on <severity>\", \"Fail threshold\", \"error\")\n .action(async (file: string, options) => {\n await runPreflightAction(program, file, { ...options, scanners: \"permissions\" });\n });\n\n // Subcommand: preflight metadata\n cmd\n .command(\"metadata <dir>\")\n .description(\"Run metadata scanner on a listings directory\")\n .option(\"--fail-on <severity>\", \"Fail threshold\", \"error\")\n .action(async (dir: string, options) => {\n await runPreflightAction(program, undefined, {\n ...options,\n metadata: dir,\n scanners: \"metadata\",\n });\n });\n\n // Subcommand: preflight codescan\n cmd\n .command(\"codescan <dir>\")\n .description(\"Run code scanners (secrets, billing, privacy) on source directory\")\n .option(\"--fail-on <severity>\", \"Fail threshold\", \"error\")\n .action(async (dir: string, options) => {\n await runPreflightAction(program, undefined, {\n ...options,\n source: dir,\n scanners: \"secrets,billing,privacy\",\n });\n });\n\n // Subcommand: preflight signing\n cmd\n .command(\"signing\")\n .description(\"Check signing key consistency across releases (requires auth)\")\n .action(async (_options, subcmd) => {\n const parentOpts = subcmd.parent?.parent?.opts() ?? {};\n const jsonMode = !!(parentOpts[\"json\"] || parentOpts[\"output\"] === \"json\");\n\n const config = await loadConfig();\n const packageName = (parentOpts[\"app\"] as string | undefined) ?? config.app;\n if (!packageName) {\n throw new GpcError(\n \"No app configured\",\n \"MISSING_APP\",\n 2,\n \"Set a default app with 'gpc config set app <package>' or use --app\",\n );\n }\n\n const { resolveAuth } = await import(\"@gpc-cli/auth\");\n const client = await resolveAuth({\n serviceAccountPath: config.auth?.serviceAccount,\n });\n const accessToken = await client.getAccessToken();\n\n const { checkSigningConsistency } = await import(\"@gpc-cli/core\");\n const result = await checkSigningConsistency(accessToken, packageName);\n\n if (jsonMode) {\n console.log(JSON.stringify(result, null, 2));\n } else {\n console.log(\"\");\n console.log(bold(\"Signing Key Consistency\"));\n console.log(\"\");\n if (result.firstRelease) {\n console.log(\n ` ${dim(\"ℹ\")} First release (v${result.currentVersionCode}): ${result.currentFingerprint}`,\n );\n console.log(` ${dim(\"Nothing to compare against yet.\")}`);\n } else if (result.consistent) {\n console.log(\n ` ${green(\"✓\")} Consistent: v${result.previousVersionCode} → v${result.currentVersionCode}`,\n );\n console.log(` ${dim(\"Fingerprint:\")} ${result.currentFingerprint}`);\n } else {\n console.log(\n ` ${red(\"✗\")} Signing key changed between v${result.previousVersionCode} and v${result.currentVersionCode}`,\n );\n console.log(` ${dim(\"Previous:\")} ${result.previousFingerprint}`);\n console.log(` ${dim(\"Current:\")} ${result.currentFingerprint}`);\n console.log(\"\");\n console.log(\n ` ${yellow(\"⚠\")} If intentional, register the new key in Play Console before September 2026.`,\n );\n }\n console.log(\"\");\n }\n\n if (!result.consistent) {\n process.exitCode = 6;\n }\n });\n}\n\nasync function runPreflightAction(\n program: Command,\n file: string | undefined,\n options: Record<string, string | undefined>,\n): Promise<void> {\n if (!file && !options[\"metadata\"] && !options[\"source\"]) {\n throw new GpcError(\n \"Provide an AAB file, --metadata <dir>, or --source <dir>\",\n \"MISSING_INPUT\",\n 2,\n \"gpc preflight app.aab\",\n );\n }\n\n const failOn = options[\"failOn\"] as FindingSeverity | undefined;\n const validSeverities = new Set([\"critical\", \"error\", \"warning\", \"info\"]);\n if (failOn && !validSeverities.has(failOn)) {\n throw new GpcError(\n `Invalid --fail-on value \"${failOn}\". Use: critical, error, warning, info`,\n \"INVALID_OPTION\",\n 2,\n );\n }\n\n const scannerNames = options[\"scanners\"]?.split(\",\").map((s) => s.trim());\n if (scannerNames) {\n const known = new Set(getAllScannerNames());\n const unknown = scannerNames.filter((s) => !known.has(s));\n if (unknown.length > 0) {\n throw new GpcError(\n `Unknown scanner(s): ${unknown.join(\", \")}. Available: ${getAllScannerNames().join(\", \")}`,\n \"UNKNOWN_SCANNER\",\n 2,\n );\n }\n }\n\n const config = await loadConfig();\n const format = getOutputFormat(program, config);\n\n const result = await runPreflight({\n aabPath: file,\n metadataDir: options[\"metadata\"],\n sourceDir: options[\"source\"],\n scanners: scannerNames,\n failOn,\n configPath: options[\"config\"],\n });\n\n if (format === \"json\") {\n console.log(formatOutput(result, format));\n } else {\n // Header\n console.log(bold(\"GPC Preflight Scanner\"));\n if (file) console.log(dim(`File: ${file}`));\n console.log(dim(`Scanners: ${result.scanners.join(\", \")}`));\n console.log(\"\");\n\n if (result.findings.length === 0) {\n console.log(green(\"✓ No issues found\"));\n } else {\n // Group by severity\n for (const finding of result.findings) {\n const icon = SEVERITY_ICONS[finding.severity];\n const label = severityColor(finding.severity, `${icon} ${finding.severity.toUpperCase()}`);\n console.log(`${label} ${finding.title}`);\n console.log(` ${dim(finding.message)}`);\n if (finding.suggestion) {\n console.log(` ${dim(\"→\")} ${finding.suggestion}`);\n }\n if (finding.policyUrl) {\n console.log(` ${dim(finding.policyUrl)}`);\n }\n console.log(\"\");\n }\n }\n\n // Summary line\n const parts: string[] = [];\n if (result.summary.critical > 0) parts.push(bold(red(`${result.summary.critical} critical`)));\n if (result.summary.error > 0) parts.push(red(`${result.summary.error} error`));\n if (result.summary.warning > 0) parts.push(yellow(`${result.summary.warning} warning`));\n if (result.summary.info > 0) parts.push(dim(`${result.summary.info} info`));\n\n const summaryLine = parts.length > 0 ? parts.join(\", \") : green(\"0 issues\");\n const passedLabel = result.passed ? green(\"✓ PASSED\") : red(\"✗ FAILED\");\n console.log(`${passedLabel} ${summaryLine} ${dim(`(${result.durationMs}ms)`)}`);\n\n // Verification deadline awareness (auto-expires Sep 2026)\n if (Date.now() < new Date(\"2026-09-01\").getTime()) {\n console.log(\"\");\n console.log(\n dim(\"Note: Apps must be registered by a verified developer to be installable on\"),\n );\n console.log(dim(\"certified Android devices after Sep 2026. Run 'gpc verify' for details.\"));\n }\n }\n\n if (!result.passed) {\n process.exitCode = 6;\n }\n}\n"],"mappings":"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","names":[]}
@@ -17,7 +17,7 @@ function registerUpdateCommand(program) {
17
17
  program.command("update").description("Update gpc to the latest version").option("--check", "Check for updates without installing (exits 0 always)").option("--force", "Update even if already on the latest version").action(async (opts, cmd) => {
18
18
  const parentOpts = cmd.parent?.opts() ?? {};
19
19
  const jsonMode = !!(parentOpts["json"] || parentOpts["output"] === "json");
20
- const currentVersion = "0.9.64";
20
+ const currentVersion = "0.9.66";
21
21
  if (currentVersion === "0.0.0") {
22
22
  if (jsonMode) {
23
23
  console.log(
@@ -172,4 +172,4 @@ Run: gpc update`);
172
172
  export {
173
173
  registerUpdateCommand
174
174
  };
175
- //# sourceMappingURL=update-E4VGHQUR.js.map
175
+ //# sourceMappingURL=update-GEH352BE.js.map
@@ -0,0 +1,330 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ isInteractive,
4
+ promptConfirm
5
+ } from "./chunk-RZQSEDKI.js";
6
+ import {
7
+ bold,
8
+ dim,
9
+ green,
10
+ red,
11
+ yellow
12
+ } from "./chunk-FAN4ZITI.js";
13
+
14
+ // src/commands/verify.ts
15
+ import { resolveAuth } from "@gpc-cli/auth";
16
+ import { loadConfig } from "@gpc-cli/config";
17
+ import { buildChecklist, renderChecklistMarkdown } from "@gpc-cli/core";
18
+ var ENFORCEMENT_DATE = /* @__PURE__ */ new Date("2026-09-30");
19
+ var ENFORCEMENT_REGIONS = ["Brazil", "Indonesia", "Singapore", "Thailand"];
20
+ var ENFORCEMENT_REGION_CODES = ["BR", "ID", "SG", "TH"];
21
+ var API_HOST = "androidpublisher.googleapis.com";
22
+ var RESOURCES = {
23
+ overview: "https://developer.android.com/developer-verification",
24
+ playConsole: "https://developer.android.com/developer-verification/guides/google-play-console",
25
+ androidConsole: "https://developer.android.com/developer-verification/guides/android-developer-console",
26
+ limitedDistribution: "https://developer.android.com/developer-verification/guides/limited-distribution",
27
+ faq: "https://developer.android.com/developer-verification/faq"
28
+ };
29
+ function daysUntilEnforcement() {
30
+ return Math.ceil((ENFORCEMENT_DATE.getTime() - Date.now()) / (1e3 * 60 * 60 * 24));
31
+ }
32
+ function isBeforeEnforcement() {
33
+ return Date.now() < ENFORCEMENT_DATE.getTime();
34
+ }
35
+ function formatDeadline() {
36
+ const days = daysUntilEnforcement();
37
+ if (days > 0) {
38
+ return `Enforcement begins September 30, 2026 (${days} days, ${ENFORCEMENT_REGION_CODES.join("/")})`;
39
+ }
40
+ return "Enforcement active. Verify your account is compliant.";
41
+ }
42
+ async function openUrl(url) {
43
+ const { execFile } = await import("child_process");
44
+ const cmd = process.platform === "darwin" ? "open" : process.platform === "win32" ? "cmd" : "xdg-open";
45
+ const args = process.platform === "win32" ? ["/c", "start", "", url] : [url];
46
+ execFile(cmd, args, (err) => {
47
+ if (err) console.error(dim(`Could not open browser: ${err.message}`));
48
+ });
49
+ }
50
+ async function probeApp(accessToken, packageName) {
51
+ const baseUrl = `https://${API_HOST}/androidpublisher/v3/applications/${encodeURIComponent(packageName)}`;
52
+ const result = {
53
+ accessible: false,
54
+ bundleCount: 0,
55
+ hasGeneratedApks: false
56
+ };
57
+ const editResp = await fetch(`${baseUrl}/edits`, {
58
+ method: "POST",
59
+ headers: { Authorization: `Bearer ${accessToken}`, "Content-Type": "application/json" },
60
+ body: JSON.stringify({}),
61
+ signal: AbortSignal.timeout(1e4)
62
+ });
63
+ if (!editResp.ok) return result;
64
+ const edit = await editResp.json();
65
+ result.accessible = true;
66
+ try {
67
+ const bundlesResp = await fetch(`${baseUrl}/edits/${edit.id}/bundles`, {
68
+ headers: { Authorization: `Bearer ${accessToken}` },
69
+ signal: AbortSignal.timeout(1e4)
70
+ });
71
+ if (bundlesResp.ok) {
72
+ const data = await bundlesResp.json();
73
+ const bundles = data.bundles ?? [];
74
+ result.bundleCount = bundles.length;
75
+ if (bundles.length > 0) {
76
+ result.latestVersionCode = bundles.reduce(
77
+ (max, b) => b.versionCode > max.versionCode ? b : max
78
+ ).versionCode;
79
+ const apksResp = await fetch(`${baseUrl}/generatedApks/${result.latestVersionCode}`, {
80
+ headers: { Authorization: `Bearer ${accessToken}` },
81
+ signal: AbortSignal.timeout(1e4)
82
+ });
83
+ if (apksResp.ok) {
84
+ const apksData = await apksResp.json();
85
+ result.hasGeneratedApks = (apksData.generatedApks?.length ?? 0) > 0;
86
+ }
87
+ }
88
+ }
89
+ } finally {
90
+ await fetch(`${baseUrl}/edits/${edit.id}`, {
91
+ method: "DELETE",
92
+ headers: { Authorization: `Bearer ${accessToken}` },
93
+ signal: AbortSignal.timeout(5e3)
94
+ }).catch(() => {
95
+ });
96
+ }
97
+ return result;
98
+ }
99
+ function registerVerifyCommand(program) {
100
+ const verify = program.command("verify").description("Android developer verification status and resources").option("--open", "Open the verification page in your browser").action(async (opts, cmd) => {
101
+ const parentOpts = cmd.parent?.opts() ?? {};
102
+ const jsonMode = !!(parentOpts["json"] || parentOpts["output"] === "json");
103
+ let accountEmail = "unknown";
104
+ let accessToken;
105
+ let config;
106
+ try {
107
+ config = await loadConfig();
108
+ const client = await resolveAuth({
109
+ serviceAccountPath: config.auth?.serviceAccount
110
+ });
111
+ accountEmail = client.getClientEmail();
112
+ accessToken = await client.getAccessToken();
113
+ } catch {
114
+ }
115
+ if (opts["open"]) {
116
+ await openUrl(RESOURCES.overview);
117
+ if (jsonMode) {
118
+ console.log(JSON.stringify({ opened: RESOURCES.overview }));
119
+ } else {
120
+ console.log(`Opened ${RESOURCES.overview}`);
121
+ }
122
+ return;
123
+ }
124
+ const packageName = parentOpts["app"] ?? config?.app;
125
+ let appInfo;
126
+ if (accessToken && packageName) {
127
+ try {
128
+ appInfo = await probeApp(accessToken, packageName);
129
+ } catch {
130
+ }
131
+ }
132
+ const days = daysUntilEnforcement();
133
+ const actionItems = [];
134
+ if (!accessToken) {
135
+ actionItems.push({
136
+ priority: "high",
137
+ title: "Authenticate with Google Play",
138
+ command: "gpc auth login"
139
+ });
140
+ }
141
+ if (appInfo && appInfo.bundleCount === 0) {
142
+ actionItems.push({
143
+ priority: "medium",
144
+ title: "Upload your first AAB",
145
+ command: "gpc publish"
146
+ });
147
+ }
148
+ if (appInfo && !appInfo.hasGeneratedApks) {
149
+ actionItems.push({
150
+ priority: "medium",
151
+ title: "Enroll in Play App Signing"
152
+ });
153
+ }
154
+ if (days > 0 && days <= 90) {
155
+ actionItems.push({
156
+ priority: "high",
157
+ title: "Enforcement is less than 90 days away. Complete verification now."
158
+ });
159
+ }
160
+ actionItems.push({
161
+ priority: "low",
162
+ title: "Run full readiness walkthrough",
163
+ command: "gpc verify checklist"
164
+ });
165
+ if (jsonMode) {
166
+ console.log(
167
+ JSON.stringify(
168
+ {
169
+ enforcement: {
170
+ date: "2026-09-30",
171
+ daysRemaining: days,
172
+ regions: ENFORCEMENT_REGIONS,
173
+ active: !isBeforeEnforcement()
174
+ },
175
+ account: accountEmail,
176
+ app: appInfo ? {
177
+ packageName,
178
+ accessible: appInfo.accessible,
179
+ bundleCount: appInfo.bundleCount,
180
+ latestVersionCode: appInfo.latestVersionCode,
181
+ playAppSigningEnrolled: appInfo.hasGeneratedApks
182
+ } : void 0,
183
+ actionItems,
184
+ resources: RESOURCES
185
+ },
186
+ null,
187
+ 2
188
+ )
189
+ );
190
+ return;
191
+ }
192
+ console.log("");
193
+ console.log(bold("Android Developer Verification"));
194
+ console.log("");
195
+ console.log(` Status: ${days <= 90 ? yellow(formatDeadline()) : dim(formatDeadline())}`);
196
+ console.log(` Account: ${accountEmail}`);
197
+ if (appInfo) {
198
+ console.log(` App: ${packageName}`);
199
+ console.log(
200
+ ` Bundles: ${appInfo.bundleCount}${appInfo.latestVersionCode ? ` (latest: v${appInfo.latestVersionCode})` : ""}`
201
+ );
202
+ console.log(
203
+ ` Signing: ${appInfo.hasGeneratedApks ? green("Play App Signing enrolled") : yellow("Not enrolled or no bundles")}`
204
+ );
205
+ }
206
+ console.log("");
207
+ if (actionItems.length > 1) {
208
+ console.log(" Action items:");
209
+ for (const item of actionItems) {
210
+ const icon = item.priority === "high" ? red("!") : item.priority === "medium" ? yellow("!") : dim("-");
211
+ const cmdHint = item.command ? ` ${dim(`\u2192 ${item.command}`)}` : "";
212
+ console.log(` ${icon} ${item.title}${cmdHint}`);
213
+ }
214
+ console.log("");
215
+ }
216
+ console.log(" Resources:");
217
+ console.log(` ${dim("\u2192")} ${RESOURCES.overview}`);
218
+ console.log(` ${dim("\u2192")} ${RESOURCES.playConsole}`);
219
+ console.log(` ${dim("\u2192")} ${RESOURCES.faq}`);
220
+ console.log("");
221
+ console.log(dim(" Run 'gpc verify --open' to open the verification page in your browser."));
222
+ console.log(dim(" Full guide: gpc docs developer-verification"));
223
+ console.log("");
224
+ });
225
+ verify.command("checklist").description("Verification readiness walkthrough").action(async (_opts, subcmd) => {
226
+ const parentOpts = subcmd.parent?.parent?.opts() ?? {};
227
+ const jsonMode = !!(parentOpts["json"] || parentOpts["output"] === "json");
228
+ const interactive = isInteractive(subcmd.parent?.parent);
229
+ let accountEmail = "unknown";
230
+ let accessToken;
231
+ let config;
232
+ let authenticated = false;
233
+ try {
234
+ config = await loadConfig();
235
+ const client = await resolveAuth({
236
+ serviceAccountPath: config.auth?.serviceAccount
237
+ });
238
+ accountEmail = client.getClientEmail();
239
+ accessToken = await client.getAccessToken();
240
+ authenticated = true;
241
+ } catch {
242
+ }
243
+ const packageName = parentOpts["app"] ?? config?.app;
244
+ let appAccessible;
245
+ let bundleCount;
246
+ let hasGeneratedApks;
247
+ if (accessToken && packageName) {
248
+ try {
249
+ const probe = await probeApp(accessToken, packageName);
250
+ appAccessible = probe.accessible;
251
+ bundleCount = probe.bundleCount;
252
+ hasGeneratedApks = probe.hasGeneratedApks;
253
+ } catch {
254
+ }
255
+ }
256
+ const interactiveAnswers = {};
257
+ if (interactive && !jsonMode && !parentOpts["json"]) {
258
+ console.log("");
259
+ console.log(bold("Developer Verification Checklist"));
260
+ console.log(dim(" Answer Y/N for items we cannot auto-detect.\n"));
261
+ const manualSteps = [
262
+ {
263
+ id: "identity-verified",
264
+ question: "Have you completed identity verification in Play Console?"
265
+ },
266
+ {
267
+ id: "auto-registration-reviewed",
268
+ question: "Have you reviewed your auto-registration results in Play Console?"
269
+ },
270
+ {
271
+ id: "additional-keys",
272
+ question: "Have you registered all additional signing keys used outside Play?"
273
+ }
274
+ ];
275
+ for (const step of manualSteps) {
276
+ interactiveAnswers[step.id] = await promptConfirm(step.question, false);
277
+ }
278
+ }
279
+ const result = buildChecklist({
280
+ authenticated,
281
+ accountEmail,
282
+ appAccessible,
283
+ bundleCount,
284
+ hasGeneratedApks,
285
+ interactiveAnswers: Object.keys(interactiveAnswers).length > 0 ? interactiveAnswers : void 0
286
+ });
287
+ if (jsonMode) {
288
+ console.log(JSON.stringify(result, null, 2));
289
+ return;
290
+ }
291
+ console.log("");
292
+ console.log(bold(`Verification Readiness: ${result.completed}/${result.total}`));
293
+ console.log("");
294
+ for (const item of result.items) {
295
+ let icon;
296
+ let label;
297
+ if (item.status === "done") {
298
+ icon = green("\u2713");
299
+ label = item.title;
300
+ } else if (item.status === "action-needed") {
301
+ icon = red("\u2717");
302
+ label = item.title;
303
+ } else {
304
+ icon = yellow("?");
305
+ label = item.title;
306
+ }
307
+ console.log(` ${icon} ${label}`);
308
+ if (item.detail && item.status !== "done") {
309
+ console.log(` ${dim(item.detail)}`);
310
+ }
311
+ if (item.actionUrl && item.status !== "done") {
312
+ console.log(` ${dim("\u2192")} ${item.actionUrl}`);
313
+ }
314
+ }
315
+ console.log("");
316
+ const md = renderChecklistMarkdown(result, accountEmail);
317
+ if (!interactive) {
318
+ console.log(dim("--- Markdown report ---"));
319
+ console.log(md);
320
+ } else {
321
+ console.log(
322
+ dim(" Tip: run with --json or --no-interactive to get a machine-readable report.")
323
+ );
324
+ }
325
+ });
326
+ }
327
+ export {
328
+ registerVerifyCommand
329
+ };
330
+ //# sourceMappingURL=verify-O2PSBTIC.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/commands/verify.ts"],"sourcesContent":["import type { Command } from \"commander\";\nimport { resolveAuth } from \"@gpc-cli/auth\";\nimport { loadConfig } from \"@gpc-cli/config\";\nimport { buildChecklist, renderChecklistMarkdown } from \"@gpc-cli/core\";\nimport { green, yellow, red, dim, bold } from \"../colors.js\";\nimport { isInteractive, promptConfirm } from \"../prompt.js\";\n\nconst ENFORCEMENT_DATE = new Date(\"2026-09-30\");\nconst ENFORCEMENT_REGIONS = [\"Brazil\", \"Indonesia\", \"Singapore\", \"Thailand\"];\nconst ENFORCEMENT_REGION_CODES = [\"BR\", \"ID\", \"SG\", \"TH\"];\nconst API_HOST = \"androidpublisher.googleapis.com\";\n\nconst RESOURCES = {\n overview: \"https://developer.android.com/developer-verification\",\n playConsole: \"https://developer.android.com/developer-verification/guides/google-play-console\",\n androidConsole:\n \"https://developer.android.com/developer-verification/guides/android-developer-console\",\n limitedDistribution:\n \"https://developer.android.com/developer-verification/guides/limited-distribution\",\n faq: \"https://developer.android.com/developer-verification/faq\",\n};\n\nfunction daysUntilEnforcement(): number {\n return Math.ceil((ENFORCEMENT_DATE.getTime() - Date.now()) / (1000 * 60 * 60 * 24));\n}\n\nfunction isBeforeEnforcement(): boolean {\n return Date.now() < ENFORCEMENT_DATE.getTime();\n}\n\nfunction formatDeadline(): string {\n const days = daysUntilEnforcement();\n if (days > 0) {\n return `Enforcement begins September 30, 2026 (${days} days, ${ENFORCEMENT_REGION_CODES.join(\"/\")})`;\n }\n return \"Enforcement active. Verify your account is compliant.\";\n}\n\nasync function openUrl(url: string): Promise<void> {\n const { execFile } = await import(\"node:child_process\");\n const cmd =\n process.platform === \"darwin\" ? \"open\" : process.platform === \"win32\" ? \"cmd\" : \"xdg-open\";\n const args = process.platform === \"win32\" ? [\"/c\", \"start\", \"\", url] : [url];\n execFile(cmd, args, (err) => {\n if (err) console.error(dim(`Could not open browser: ${err.message}`));\n });\n}\n\ninterface AppProbeResult {\n accessible: boolean;\n bundleCount: number;\n latestVersionCode?: number;\n hasGeneratedApks: boolean;\n}\n\nasync function probeApp(accessToken: string, packageName: string): Promise<AppProbeResult> {\n const baseUrl = `https://${API_HOST}/androidpublisher/v3/applications/${encodeURIComponent(packageName)}`;\n const result: AppProbeResult = {\n accessible: false,\n bundleCount: 0,\n hasGeneratedApks: false,\n };\n\n const editResp = await fetch(`${baseUrl}/edits`, {\n method: \"POST\",\n headers: { Authorization: `Bearer ${accessToken}`, \"Content-Type\": \"application/json\" },\n body: JSON.stringify({}),\n signal: AbortSignal.timeout(10_000),\n });\n if (!editResp.ok) return result;\n\n const edit = (await editResp.json()) as { id: string };\n result.accessible = true;\n\n try {\n const bundlesResp = await fetch(`${baseUrl}/edits/${edit.id}/bundles`, {\n headers: { Authorization: `Bearer ${accessToken}` },\n signal: AbortSignal.timeout(10_000),\n });\n if (bundlesResp.ok) {\n const data = (await bundlesResp.json()) as { bundles?: { versionCode: number }[] };\n const bundles = data.bundles ?? [];\n result.bundleCount = bundles.length;\n if (bundles.length > 0) {\n result.latestVersionCode = bundles.reduce((max, b) =>\n b.versionCode > max.versionCode ? b : max,\n ).versionCode;\n\n const apksResp = await fetch(`${baseUrl}/generatedApks/${result.latestVersionCode}`, {\n headers: { Authorization: `Bearer ${accessToken}` },\n signal: AbortSignal.timeout(10_000),\n });\n if (apksResp.ok) {\n const apksData = (await apksResp.json()) as {\n generatedApks?: { certificateSha256Fingerprint?: string }[];\n };\n result.hasGeneratedApks = (apksData.generatedApks?.length ?? 0) > 0;\n }\n }\n }\n } finally {\n await fetch(`${baseUrl}/edits/${edit.id}`, {\n method: \"DELETE\",\n headers: { Authorization: `Bearer ${accessToken}` },\n signal: AbortSignal.timeout(5_000),\n }).catch(() => {});\n }\n\n return result;\n}\n\nexport function registerVerifyCommand(program: Command): void {\n const verify = program\n .command(\"verify\")\n .description(\"Android developer verification status and resources\")\n .option(\"--open\", \"Open the verification page in your browser\")\n .action(async (opts, cmd) => {\n const parentOpts = cmd.parent?.opts() ?? {};\n const jsonMode = !!(parentOpts[\"json\"] || parentOpts[\"output\"] === \"json\");\n\n let accountEmail = \"unknown\";\n let accessToken: string | undefined;\n let config;\n try {\n config = await loadConfig();\n const client = await resolveAuth({\n serviceAccountPath: config.auth?.serviceAccount,\n });\n accountEmail = client.getClientEmail();\n accessToken = await client.getAccessToken();\n } catch {\n // Auth not configured\n }\n\n if (opts[\"open\"]) {\n await openUrl(RESOURCES.overview);\n if (jsonMode) {\n console.log(JSON.stringify({ opened: RESOURCES.overview }));\n } else {\n console.log(`Opened ${RESOURCES.overview}`);\n }\n return;\n }\n\n const packageName = (parentOpts[\"app\"] as string | undefined) ?? config?.app;\n let appInfo: AppProbeResult | undefined;\n if (accessToken && packageName) {\n try {\n appInfo = await probeApp(accessToken, packageName);\n } catch {\n // Non-blocking\n }\n }\n\n const days = daysUntilEnforcement();\n const actionItems: { priority: string; title: string; command?: string }[] = [];\n\n if (!accessToken) {\n actionItems.push({\n priority: \"high\",\n title: \"Authenticate with Google Play\",\n command: \"gpc auth login\",\n });\n }\n if (appInfo && appInfo.bundleCount === 0) {\n actionItems.push({\n priority: \"medium\",\n title: \"Upload your first AAB\",\n command: \"gpc publish\",\n });\n }\n if (appInfo && !appInfo.hasGeneratedApks) {\n actionItems.push({\n priority: \"medium\",\n title: \"Enroll in Play App Signing\",\n });\n }\n if (days > 0 && days <= 90) {\n actionItems.push({\n priority: \"high\",\n title: \"Enforcement is less than 90 days away. Complete verification now.\",\n });\n }\n actionItems.push({\n priority: \"low\",\n title: \"Run full readiness walkthrough\",\n command: \"gpc verify checklist\",\n });\n\n if (jsonMode) {\n console.log(\n JSON.stringify(\n {\n enforcement: {\n date: \"2026-09-30\",\n daysRemaining: days,\n regions: ENFORCEMENT_REGIONS,\n active: !isBeforeEnforcement(),\n },\n account: accountEmail,\n app: appInfo\n ? {\n packageName,\n accessible: appInfo.accessible,\n bundleCount: appInfo.bundleCount,\n latestVersionCode: appInfo.latestVersionCode,\n playAppSigningEnrolled: appInfo.hasGeneratedApks,\n }\n : undefined,\n actionItems,\n resources: RESOURCES,\n },\n null,\n 2,\n ),\n );\n return;\n }\n\n console.log(\"\");\n console.log(bold(\"Android Developer Verification\"));\n console.log(\"\");\n console.log(` Status: ${days <= 90 ? yellow(formatDeadline()) : dim(formatDeadline())}`);\n console.log(` Account: ${accountEmail}`);\n if (appInfo) {\n console.log(` App: ${packageName}`);\n console.log(\n ` Bundles: ${appInfo.bundleCount}${appInfo.latestVersionCode ? ` (latest: v${appInfo.latestVersionCode})` : \"\"}`,\n );\n console.log(\n ` Signing: ${appInfo.hasGeneratedApks ? green(\"Play App Signing enrolled\") : yellow(\"Not enrolled or no bundles\")}`,\n );\n }\n console.log(\"\");\n\n if (actionItems.length > 1) {\n console.log(\" Action items:\");\n for (const item of actionItems) {\n const icon =\n item.priority === \"high\"\n ? red(\"!\")\n : item.priority === \"medium\"\n ? yellow(\"!\")\n : dim(\"-\");\n const cmdHint = item.command ? ` ${dim(`→ ${item.command}`)}` : \"\";\n console.log(` ${icon} ${item.title}${cmdHint}`);\n }\n console.log(\"\");\n }\n\n console.log(\" Resources:\");\n console.log(` ${dim(\"→\")} ${RESOURCES.overview}`);\n console.log(` ${dim(\"→\")} ${RESOURCES.playConsole}`);\n console.log(` ${dim(\"→\")} ${RESOURCES.faq}`);\n console.log(\"\");\n console.log(dim(\" Run 'gpc verify --open' to open the verification page in your browser.\"));\n console.log(dim(\" Full guide: gpc docs developer-verification\"));\n console.log(\"\");\n });\n\n verify\n .command(\"checklist\")\n .description(\"Verification readiness walkthrough\")\n .action(async (_opts, subcmd) => {\n const parentOpts = subcmd.parent?.parent?.opts() ?? {};\n const jsonMode = !!(parentOpts[\"json\"] || parentOpts[\"output\"] === \"json\");\n const interactive = isInteractive(subcmd.parent?.parent);\n\n let accountEmail = \"unknown\";\n let accessToken: string | undefined;\n let config;\n let authenticated = false;\n try {\n config = await loadConfig();\n const client = await resolveAuth({\n serviceAccountPath: config.auth?.serviceAccount,\n });\n accountEmail = client.getClientEmail();\n accessToken = await client.getAccessToken();\n authenticated = true;\n } catch {\n // Auth not configured\n }\n\n const packageName = (parentOpts[\"app\"] as string | undefined) ?? config?.app;\n let appAccessible: boolean | undefined;\n let bundleCount: number | undefined;\n let hasGeneratedApks: boolean | undefined;\n\n if (accessToken && packageName) {\n try {\n const probe = await probeApp(accessToken, packageName);\n appAccessible = probe.accessible;\n bundleCount = probe.bundleCount;\n hasGeneratedApks = probe.hasGeneratedApks;\n } catch {\n // Non-blocking\n }\n }\n\n const interactiveAnswers: Record<string, boolean> = {};\n if (interactive && !jsonMode && !parentOpts[\"json\"]) {\n console.log(\"\");\n console.log(bold(\"Developer Verification Checklist\"));\n console.log(dim(\" Answer Y/N for items we cannot auto-detect.\\n\"));\n\n const manualSteps = [\n {\n id: \"identity-verified\",\n question: \"Have you completed identity verification in Play Console?\",\n },\n {\n id: \"auto-registration-reviewed\",\n question: \"Have you reviewed your auto-registration results in Play Console?\",\n },\n {\n id: \"additional-keys\",\n question: \"Have you registered all additional signing keys used outside Play?\",\n },\n ];\n\n for (const step of manualSteps) {\n interactiveAnswers[step.id] = await promptConfirm(step.question, false);\n }\n }\n\n const result = buildChecklist({\n authenticated,\n accountEmail,\n appAccessible,\n bundleCount,\n hasGeneratedApks,\n interactiveAnswers:\n Object.keys(interactiveAnswers).length > 0 ? interactiveAnswers : undefined,\n });\n\n if (jsonMode) {\n console.log(JSON.stringify(result, null, 2));\n return;\n }\n\n console.log(\"\");\n console.log(bold(`Verification Readiness: ${result.completed}/${result.total}`));\n console.log(\"\");\n\n for (const item of result.items) {\n let icon: string;\n let label: string;\n if (item.status === \"done\") {\n icon = green(\"✓\");\n label = item.title;\n } else if (item.status === \"action-needed\") {\n icon = red(\"✗\");\n label = item.title;\n } else {\n icon = yellow(\"?\");\n label = item.title;\n }\n console.log(` ${icon} ${label}`);\n if (item.detail && item.status !== \"done\") {\n console.log(` ${dim(item.detail)}`);\n }\n if (item.actionUrl && item.status !== \"done\") {\n console.log(` ${dim(\"→\")} ${item.actionUrl}`);\n }\n }\n\n console.log(\"\");\n\n const md = renderChecklistMarkdown(result, accountEmail);\n if (!interactive) {\n console.log(dim(\"--- Markdown report ---\"));\n console.log(md);\n } else {\n console.log(\n dim(\" Tip: run with --json or --no-interactive to get a machine-readable report.\"),\n );\n }\n });\n}\n"],"mappings":"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","names":[]}
@@ -7,7 +7,7 @@ import "./chunk-3SJ6OXCZ.js";
7
7
  // src/commands/version.ts
8
8
  function registerVersionCommand(program) {
9
9
  program.command("version").description("Show version information").action(() => {
10
- const version = "0.9.64";
10
+ const version = "0.9.66";
11
11
  if (program.opts()["output"] === "json") {
12
12
  console.log(
13
13
  JSON.stringify({
@@ -25,4 +25,4 @@ function registerVersionCommand(program) {
25
25
  export {
26
26
  registerVersionCommand
27
27
  };
28
- //# sourceMappingURL=version-HXUIOHCL.js.map
28
+ //# sourceMappingURL=version-2RUEWMPK.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gpc-cli/cli",
3
- "version": "0.9.64",
3
+ "version": "0.9.66",
4
4
  "description": "GPC — Google Play Console CLI. 217 API endpoints including Managed Google Play. Upload AABs, manage releases, monitor vitals, publish private enterprise apps. Fastlane alternative for Android.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -19,10 +19,10 @@
19
19
  ],
20
20
  "dependencies": {
21
21
  "commander": "^14.0.3",
22
- "@gpc-cli/api": "1.0.36",
23
- "@gpc-cli/config": "0.9.14",
24
- "@gpc-cli/core": "0.9.54",
25
22
  "@gpc-cli/auth": "0.9.14",
23
+ "@gpc-cli/config": "0.9.14",
24
+ "@gpc-cli/core": "0.9.56",
25
+ "@gpc-cli/api": "1.0.36",
26
26
  "@gpc-cli/plugin-sdk": "0.9.10"
27
27
  },
28
28
  "keywords": [
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/commands/changelog.ts"],"sourcesContent":["import type { Command } from \"commander\";\nimport {\n fetchChangelog,\n formatChangelogEntry,\n formatOutput,\n generateChangelog,\n RENDERERS,\n renderPlayStore,\n renderPlayStoreMd,\n renderPlayStorePrompt,\n buildLocaleBundle,\n translateBundle,\n resolveAiConfig,\n createTranslator,\n fetchAggregateCost,\n formatPathLabel,\n PROVIDER_WHITELIST,\n resolveLocales,\n validateBundleForApply,\n bundleToReleaseNotes,\n applyReleaseNotes,\n GpcError,\n type OutputMode,\n type PlayStoreFormat,\n} from \"@gpc-cli/core\";\nimport { loadConfig } from \"@gpc-cli/config\";\nimport { getOutputFormat } from \"../format.js\";\nimport { yellow, dim } from \"../colors.js\";\nimport { resolvePackageName, getClient } from \"../resolve.js\";\n\nconst VALID_OUTPUT_MODES: OutputMode[] = [\"md\", \"json\", \"prompt\"];\nconst VALID_TARGETS = [\"github\", \"play-store\"] as const;\ntype ChangelogTarget = (typeof VALID_TARGETS)[number];\nconst REPO_RE = /^[A-Za-z0-9_.-]+\\/[A-Za-z0-9_.-]+$/;\n\ninterface ApplyContext {\n bundle: Parameters<typeof validateBundleForApply>[0];\n program: Command;\n track: string;\n dryRun: boolean;\n aiBlock?: Record<string, unknown>;\n}\n\nasync function performApply(ctx: ApplyContext): Promise<boolean> {\n const blocked = validateBundleForApply(ctx.bundle);\n if (blocked.length > 0) {\n process.stderr.write(\n `Cannot --apply: ${blocked.length} locale(s) blocked:\\n` +\n blocked.map((b) => ` ${b}`).join(\"\\n\") +\n \"\\n\",\n );\n process.exitCode = 1;\n return false;\n }\n const notes = bundleToReleaseNotes(ctx.bundle);\n const config = await loadConfig();\n const packageName = resolvePackageName(ctx.program.opts()[\"app\"], config);\n if (ctx.dryRun) {\n const payload: Record<string, unknown> = {\n dryRun: true, action: \"apply release notes\", track: ctx.track,\n packageName, localeCount: notes.length, releaseNotes: notes,\n };\n if (ctx.aiBlock) payload[\"ai\"] = ctx.aiBlock;\n console.log(JSON.stringify(payload, null, 2));\n return false;\n }\n const client = await getClient(config);\n const result = await applyReleaseNotes(client, packageName, ctx.track, notes);\n process.stderr.write(\n `${dim(`→ Applied ${result.localeCount} locale(s) to draft on ${result.track} (${packageName})`)}\\n`,\n );\n return true;\n}\n\nexport function registerChangelogCommand(program: Command): void {\n const changelog = program\n .command(\"changelog\")\n .description(\"Show release history\")\n .option(\"-n, --limit <count>\", \"Number of releases to show\", parseInt, 5)\n .option(\"--tag <tag>\", \"Show a specific release (e.g., v0.9.43)\")\n .option(\"--all\", \"Show all releases\")\n .action(async (opts: { limit: number; tag?: string; all?: boolean }) => {\n const config = await loadConfig();\n const format = getOutputFormat(program, config);\n\n const entries = await fetchChangelog({\n limit: opts.all ? 100 : opts.limit,\n version: opts.tag,\n });\n\n if (entries.length === 0) {\n console.log(\"No releases found.\");\n return;\n }\n\n if (format === \"json\") {\n console.log(formatOutput(entries, \"json\"));\n return;\n }\n\n if (opts.tag || entries.length === 1) {\n console.log(formatChangelogEntry(entries[0]!));\n return;\n }\n\n const header = \"VERSION DATE TITLE\";\n const separator = \"─\".repeat(header.length);\n console.log(header);\n console.log(separator);\n for (const entry of entries) {\n const version = entry.version.padEnd(12);\n const date = entry.date.padEnd(12);\n console.log(`${version} ${date} ${entry.title}`);\n }\n console.log(\"\");\n console.log(\n `Showing ${entries.length} releases. Use --tag <tag> for details, or --all for full history.`,\n );\n });\n\n changelog\n .command(\"generate\")\n .description(\"Generate release notes from local git commits\")\n .option(\"--from <ref>\", \"Starting ref (default: latest v* tag)\")\n .option(\"--to <ref>\", \"Ending ref (default: HEAD)\")\n .option(\"--format <mode>\", \"Renderer: md, json, or prompt\", \"md\")\n .option(\"--repo <owner/name>\", \"Override auto-detected repo (e.g., yasserstudio/gpc)\")\n .option(\"--target <mode>\", \"Output target: github or play-store\", \"github\")\n .option(\n \"--locales <csv|auto>\",\n \"Comma-separated BCP 47 locales, or 'auto' (play-store target only)\",\n )\n .option(\"--ai\", \"Translate non-source locales via LLM (play-store target only, BYO key)\")\n .option(\n \"--provider <name>\",\n `AI provider (${PROVIDER_WHITELIST.join(\"|\")}). Defaults to first env key detected`,\n )\n .option(\"--model <id>\", \"Override default model for the chosen provider\")\n .option(\"--strict\", \"Exit non-zero if warnings, overflows, or translation failures occur\")\n .option(\"--apply\", \"Write notes into the draft release on --track (play-store target only)\")\n .option(\"--track <name>\", \"Play Store track for --apply (default: production)\", \"production\")\n .action(\n async (opts: {\n from?: string;\n to?: string;\n format: string;\n repo?: string;\n target: string;\n locales?: string;\n strict?: boolean;\n ai?: boolean;\n provider?: string;\n model?: string;\n apply?: boolean;\n track: string;\n }) => {\n const dryRun = !!program.opts()[\"dryRun\"];\n const mode = opts.format as OutputMode;\n if (!VALID_OUTPUT_MODES.includes(mode)) {\n process.stderr.write(\n `Invalid --format \"${opts.format}\". Valid: ${VALID_OUTPUT_MODES.join(\", \")}\\n`,\n );\n process.exitCode = 2;\n return;\n }\n if (!VALID_TARGETS.includes(opts.target as ChangelogTarget)) {\n process.stderr.write(\n `Invalid --target \"${opts.target}\". Valid: ${VALID_TARGETS.join(\", \")}\\n`,\n );\n process.exitCode = 2;\n return;\n }\n const target = opts.target as ChangelogTarget;\n if (opts.repo && !REPO_RE.test(opts.repo)) {\n process.stderr.write(\n `Invalid --repo \"${opts.repo}\". Expected \"owner/name\" (e.g., yasserstudio/gpc).\\n`,\n );\n process.exitCode = 2;\n return;\n }\n if (target === \"github\" && opts.locales) {\n process.stderr.write(\n `--locales only applies to --target play-store (current target: github)\\n`,\n );\n process.exitCode = 2;\n return;\n }\n // Only block when the AI-adjacent flags are explicitly set. The root\n // program has its own `--dry-run` flag that may already be set\n // globally by the user for unrelated reasons; we silently ignore it\n // on non-AI code paths.\n if (target === \"github\" && (opts.ai || opts.provider || opts.model)) {\n process.stderr.write(\"--ai / --provider / --model only apply to --target play-store\\n\");\n process.exitCode = 2;\n return;\n }\n // --format prompt + --ai is nonsensical outside --dry-run: it would\n // render a \"please translate this\" prompt from already-translated\n // text. Either inspect the prompt via --dry-run, or pick md/json.\n if (opts.ai && opts.format === \"prompt\" && !dryRun) {\n process.stderr.write(\n \"--ai with --format prompt only makes sense with --dry-run\\n\" +\n \" (otherwise it would re-wrap translated text in a translation prompt).\\n\" +\n \" Hint: use --format md or --format json for live translation, or add --dry-run to inspect the prompt.\\n\",\n );\n process.exitCode = 2;\n return;\n }\n if (opts.apply && target !== \"play-store\") {\n process.stderr.write(\"--apply only applies to --target play-store\\n\");\n process.exitCode = 2;\n return;\n }\n if (opts.apply && mode === \"prompt\") {\n process.stderr.write(\n \"--apply cannot be combined with --format prompt\\n\" +\n \" Hint: use --format md or --format json.\\n\",\n );\n process.exitCode = 2;\n return;\n }\n if (target === \"play-store\" && !opts.locales) {\n process.stderr.write(\n \"--target play-store requires --locales <csv|auto>\\n\" +\n \" Example: --locales en-US,fr-FR,de-DE\\n\" +\n \" Example: --locales auto (reads current Play Store listing — requires --app)\\n\",\n );\n process.exitCode = 2;\n return;\n }\n\n const generated = await generateChangelog({\n from: opts.from,\n to: opts.to,\n repo: opts.repo,\n });\n\n for (const w of generated.warnings) {\n process.stderr.write(`${yellow(\"warn:\")} ${w}\\n`);\n }\n if (generated.warnings.length > 0) {\n process.stderr.write(\n `${dim(`(${generated.warnings.length} warning${generated.warnings.length === 1 ? \"\" : \"s\"} — review before publishing)`)}\\n`,\n );\n }\n\n if (target === \"github\") {\n const output = RENDERERS[mode](generated);\n console.log(output);\n if (opts.strict && generated.warnings.length > 0) {\n process.exitCode = 1;\n }\n return;\n }\n\n // target === \"play-store\"\n let locales: string[];\n try {\n if (opts.locales === \"auto\") {\n const config = await loadConfig();\n const packageName = resolvePackageName(program.opts()[\"app\"], config);\n const client = await getClient(config);\n locales = await resolveLocales(\"auto\", { client, packageName });\n } else {\n locales = await resolveLocales(opts.locales!);\n }\n } catch (error) {\n if (error instanceof GpcError) {\n process.stderr.write(`${error.message}\\n`);\n if (error.suggestion) process.stderr.write(`${dim(error.suggestion)}\\n`);\n process.exitCode = error.exitCode;\n return;\n }\n throw error;\n }\n\n const playStoreFormat = mode as PlayStoreFormat;\n\n // Non-AI path: existing v0.9.62 behavior\n if (!opts.ai) {\n const { output, bundle } = renderPlayStore(generated, {\n locales,\n format: playStoreFormat,\n });\n console.log(output);\n\n for (const lang of bundle.overflows) {\n process.stderr.write(\n `${yellow(\"warn:\")} ${lang} exceeds ${bundle.limit} chars (truncated)\\n`,\n );\n }\n\n if (opts.apply) {\n const ok = await performApply({ bundle, program, track: opts.track, dryRun });\n if (!ok) return;\n }\n\n const hasOverflow = bundle.overflows.length > 0;\n const hasWarnings = generated.warnings.length > 0;\n if (opts.strict && (hasWarnings || hasOverflow)) {\n process.exitCode = 1;\n }\n return;\n }\n\n // --ai path: resolve config, translate, render with ai block\n let aiConfig;\n try {\n aiConfig = resolveAiConfig({ provider: opts.provider, model: opts.model });\n } catch (error) {\n if (error instanceof GpcError) {\n process.stderr.write(`${error.message}\\n`);\n if (error.suggestion) process.stderr.write(`${dim(error.suggestion)}\\n`);\n process.exitCode = error.exitCode;\n return;\n }\n throw error;\n }\n\n process.stderr.write(`${dim(`→ ${formatPathLabel(aiConfig)}`)}\\n`);\n\n const baseBundle = buildLocaleBundle(generated, {\n locales,\n format: playStoreFormat,\n });\n\n if (dryRun) {\n const preview = renderPlayStorePrompt(baseBundle, generated);\n console.log(preview);\n process.stderr.write(\n `${dim(\"(--dry-run: no API call was made; the prompt above is what would be sent per locale)\")}\\n`,\n );\n return;\n }\n\n const translator = await createTranslator(aiConfig);\n let translated;\n try {\n translated = await translateBundle(baseBundle, {\n translator,\n strict: opts.strict,\n onError: ({ language, reason }) => {\n process.stderr.write(\n `${yellow(\"warn:\")} ${language} translation failed: ${reason}\\n`,\n );\n },\n });\n } catch (error) {\n if (error instanceof GpcError) {\n process.stderr.write(`${error.message}\\n`);\n if (error.suggestion) process.stderr.write(`${dim(error.suggestion)}\\n`);\n process.exitCode = error.exitCode;\n return;\n }\n throw error;\n }\n\n const costUsd =\n aiConfig.path === \"gateway\" ? await fetchAggregateCost(aiConfig.runId) : undefined;\n\n const aiBlock: Record<string, unknown> = {\n path: aiConfig.path,\n provider: aiConfig.provider,\n model: aiConfig.model,\n tokensIn: translated.tokensIn,\n tokensOut: translated.tokensOut,\n };\n if (aiConfig.path === \"gateway\") {\n aiBlock[\"runId\"] = aiConfig.runId;\n if (typeof costUsd === \"number\") aiBlock[\"costUsd\"] = costUsd;\n }\n\n if (playStoreFormat === \"json\") {\n const payload = {\n from: translated.from,\n to: translated.to,\n limit: translated.limit,\n sourceLanguage: translated.sourceLanguage,\n ai: aiBlock,\n locales: translated.locales,\n overflows: translated.overflows,\n failures: translated.failures,\n };\n console.log(JSON.stringify(payload, null, 2));\n } else if (playStoreFormat === \"prompt\") {\n console.log(renderPlayStorePrompt(translated, generated));\n } else {\n console.log(renderPlayStoreMd(translated));\n }\n\n for (const lang of translated.overflows) {\n process.stderr.write(\n `${yellow(\"warn:\")} ${lang} exceeds ${translated.limit} chars (truncated)\\n`,\n );\n }\n\n if (translated.failures.length > 0) {\n process.stderr.write(\n `${dim(`(${translated.failures.length} locale${translated.failures.length === 1 ? \"\" : \"s\"} failed — see placeholders in output)`)}\\n`,\n );\n }\n\n if (typeof costUsd === \"number\") {\n process.stderr.write(`${dim(`(run cost: $${costUsd.toFixed(4)})`)}\\n`);\n }\n\n if (opts.apply) {\n const ok = await performApply({ bundle: translated, program, track: opts.track, dryRun, aiBlock });\n if (!ok) return;\n }\n\n const hasOverflow = translated.overflows.length > 0;\n const hasWarnings = generated.warnings.length > 0;\n const hasFailures = translated.failures.length > 0;\n if (opts.strict && (hasWarnings || hasOverflow || hasFailures)) {\n process.exitCode = 1;\n }\n },\n );\n}\n"],"mappings":"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","names":["hasOverflow","hasWarnings"]}