@gpc-cli/cli 0.9.47 → 0.9.49

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/README.md +12 -3
  2. package/dist/{audit-JASSHRWN.js → audit-VTWXTXC6.js} +5 -4
  3. package/dist/audit-VTWXTXC6.js.map +1 -0
  4. package/dist/{auth-OTA3SV3J.js → auth-BA4FE2PO.js} +85 -24
  5. package/dist/auth-BA4FE2PO.js.map +1 -0
  6. package/dist/bin.js +2 -2
  7. package/dist/{chunk-WWVURXVO.js → chunk-7A4IKNZ5.js} +19 -16
  8. package/dist/chunk-7A4IKNZ5.js.map +1 -0
  9. package/dist/{config-NY3TZGVS.js → config-JOYJ7TQC.js} +2 -2
  10. package/dist/{doctor-QCCWG6Y3.js → doctor-Q4WI432G.js} +38 -3
  11. package/dist/doctor-Q4WI432G.js.map +1 -0
  12. package/dist/{feedback-CET2X67K.js → feedback-3JAMSICL.js} +2 -2
  13. package/dist/index.js +1 -1
  14. package/dist/{install-skills-6QDUXI5F.js → install-skills-JKPYZHYS.js} +2 -2
  15. package/dist/{install-skills-6QDUXI5F.js.map → install-skills-JKPYZHYS.js.map} +1 -1
  16. package/dist/{preflight-N7ZRG2JI.js → preflight-W3JAJ4GO.js} +14 -1
  17. package/dist/{preflight-N7ZRG2JI.js.map → preflight-W3JAJ4GO.js.map} +1 -1
  18. package/dist/{purchases-Z3QBM3UO.js → purchases-UBFLNYZC.js} +13 -2
  19. package/dist/purchases-UBFLNYZC.js.map +1 -0
  20. package/dist/{releases-276W3BR7.js → releases-OUJ65774.js} +6 -5
  21. package/dist/releases-OUJ65774.js.map +1 -0
  22. package/dist/{status-6LH5W4FU.js → status-3HXBBXG6.js} +7 -1
  23. package/dist/{status-6LH5W4FU.js.map → status-3HXBBXG6.js.map} +1 -1
  24. package/dist/{subscriptions-DZP3Y7O7.js → subscriptions-LURZFPGJ.js} +5 -4
  25. package/dist/subscriptions-LURZFPGJ.js.map +1 -0
  26. package/dist/{tracks-YHMO2A6B.js → tracks-DO7C5OSE.js} +3 -3
  27. package/dist/tracks-DO7C5OSE.js.map +1 -0
  28. package/dist/{update-XAO5EZHC.js → update-QSRQBFDJ.js} +2 -2
  29. package/dist/verify-UUQNQMPG.js +106 -0
  30. package/dist/verify-UUQNQMPG.js.map +1 -0
  31. package/dist/{version-R3P4NHCF.js → version-V2OQLSVG.js} +2 -2
  32. package/package.json +3 -3
  33. package/dist/audit-JASSHRWN.js.map +0 -1
  34. package/dist/auth-OTA3SV3J.js.map +0 -1
  35. package/dist/chunk-WWVURXVO.js.map +0 -1
  36. package/dist/doctor-QCCWG6Y3.js.map +0 -1
  37. package/dist/purchases-Z3QBM3UO.js.map +0 -1
  38. package/dist/releases-276W3BR7.js.map +0 -1
  39. package/dist/subscriptions-DZP3Y7O7.js.map +0 -1
  40. package/dist/tracks-YHMO2A6B.js.map +0 -1
  41. /package/dist/{config-NY3TZGVS.js.map → config-JOYJ7TQC.js.map} +0 -0
  42. /package/dist/{feedback-CET2X67K.js.map → feedback-3JAMSICL.js.map} +0 -0
  43. /package/dist/{update-XAO5EZHC.js.map → update-QSRQBFDJ.js.map} +0 -0
  44. /package/dist/{version-R3P4NHCF.js.map → version-V2OQLSVG.js.map} +0 -0
package/README.md CHANGED
@@ -76,6 +76,10 @@ REVIEWS (last 30 days)
76
76
 
77
77
  6 parallel API calls, results in under 3 seconds. Results cached — `--cached` skips the network entirely.
78
78
 
79
+ ## Why GPC
80
+
81
+ Fastlane supply covers ~20 of 204 Google Play API endpoints. gradle-play-publisher covers ~15. Neither gives you reviews, vitals, subscriptions, or reports. GPC covers the entire API — no Ruby, no JVM, no browser. Every write operation supports `--dry-run`. Works with your existing service account.
82
+
79
83
  ## What You Get
80
84
 
81
85
  204 API endpoints across these command groups:
@@ -128,7 +132,7 @@ JSON output when piped. Formatted tables in your terminal. Semantic exit codes (
128
132
 
129
133
  Already on Fastlane? See the [migration guide](https://yasserstudio.github.io/gpc/migration/from-fastlane) — most commands map one-to-one.
130
134
 
131
- ## Part of the GPC Monorepo
135
+ ## Related Packages
132
136
 
133
137
  | Package | Description |
134
138
  | ------------------------------------------------------------------------ | -------------------------------------------- |
@@ -140,9 +144,14 @@ Already on Fastlane? See the [migration guide](https://yasserstudio.github.io/gp
140
144
  | [@gpc-cli/plugin-sdk](https://www.npmjs.com/package/@gpc-cli/plugin-sdk) | Plugin interface and lifecycle hooks |
141
145
  | [@gpc-cli/plugin-ci](https://www.npmjs.com/package/@gpc-cli/plugin-ci) | CI/CD helpers |
142
146
 
143
- ## Documentation
147
+ ## Get Started
148
+
149
+ ```bash
150
+ npm install -g @gpc-cli/cli
151
+ gpc doctor
152
+ ```
144
153
 
145
- Full docs at **[yasserstudio.github.io/gpc](https://yasserstudio.github.io/gpc/)**
154
+ Full docs at **[yasserstudio.github.io/gpc](https://yasserstudio.github.io/gpc/)** | [GitHub](https://github.com/yasserstudio/gpc)
146
155
 
147
156
  ## License
148
157
 
@@ -17,7 +17,8 @@ import {
17
17
  listAuditEvents,
18
18
  searchAuditEvents,
19
19
  clearAuditLog,
20
- formatOutput
20
+ formatOutput,
21
+ maybePaginate
21
22
  } from "@gpc-cli/core";
22
23
  function formatAuditTimestamp(iso) {
23
24
  const date = new Date(iso);
@@ -72,9 +73,9 @@ function registerAuditCommands(program) {
72
73
  success: e.success !== void 0 ? String(e.success) : "-",
73
74
  durationMs: e.durationMs ?? "-"
74
75
  }));
75
- console.log(formatOutput(rows, format));
76
+ await maybePaginate(formatOutput(rows, format));
76
77
  } else {
77
- console.log(formatOutput(events, format));
78
+ await maybePaginate(formatOutput(events, format));
78
79
  }
79
80
  });
80
81
  audit.command("search <query>").description("Search audit events by keyword").action(async (query) => {
@@ -121,4 +122,4 @@ function registerAuditCommands(program) {
121
122
  export {
122
123
  registerAuditCommands
123
124
  };
124
- //# sourceMappingURL=audit-JASSHRWN.js.map
125
+ //# sourceMappingURL=audit-VTWXTXC6.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/commands/audit.ts"],"sourcesContent":["import type { Command } from \"commander\";\nimport { loadConfig } from \"@gpc-cli/config\";\nimport { getConfigDir } from \"@gpc-cli/config\";\nimport {\n initAudit,\n listAuditEvents,\n searchAuditEvents,\n clearAuditLog,\n formatOutput,\n maybePaginate,\n} from \"@gpc-cli/core\";\nimport { getOutputFormat } from \"../format.js\";\nimport { isDryRun } from \"../dry-run.js\";\nimport { requireConfirm } from \"../prompt.js\";\n\nfunction formatAuditTimestamp(iso: string): string {\n const date = new Date(iso);\n const now = new Date();\n const diffMs = now.getTime() - date.getTime();\n const diffMin = Math.floor(diffMs / 60000);\n if (diffMin < 60) return diffMin < 1 ? \"just now\" : `${diffMin} min ago`;\n const diffHr = Math.floor(diffMin / 60);\n if (diffHr < 24)\n return `${String(date.getHours()).padStart(2, \"0\")}:${String(date.getMinutes()).padStart(2, \"0\")}:${String(date.getSeconds()).padStart(2, \"0\")}`;\n const diffDays = Math.floor(diffHr / 24);\n if (diffDays < 7) {\n const days = [\"Sun\", \"Mon\", \"Tue\", \"Wed\", \"Thu\", \"Fri\", \"Sat\"];\n return `${days[date.getDay()]} ${String(date.getHours()).padStart(2, \"0\")}:${String(date.getMinutes()).padStart(2, \"0\")}`;\n }\n const months = [\n \"Jan\",\n \"Feb\",\n \"Mar\",\n \"Apr\",\n \"May\",\n \"Jun\",\n \"Jul\",\n \"Aug\",\n \"Sep\",\n \"Oct\",\n \"Nov\",\n \"Dec\",\n ];\n return `${months[date.getMonth()]} ${date.getDate()}, ${date.getFullYear()}`;\n}\n\nexport function registerAuditCommands(program: Command): void {\n const audit = program.command(\"audit\").description(\"Query and manage audit logs\");\n\n audit\n .command(\"list\")\n .description(\"List recent audit events\")\n .option(\"--limit <n>\", \"Maximum events to show\", parseInt, 50)\n .option(\"--since <date>\", \"Show events since date (ISO 8601)\")\n .option(\"--command <name>\", \"Filter by command name\")\n .action(async (options) => {\n const config = await loadConfig();\n const format = getOutputFormat(program, config);\n initAudit(getConfigDir());\n\n const events = await listAuditEvents({\n limit: options.limit,\n since: options.since,\n command: options.command,\n });\n if (events.length === 0 && format !== \"json\") {\n console.log(\"No audit events found.\");\n return;\n }\n if (format !== \"json\") {\n const rows = events.map((e) => ({\n timestamp: formatAuditTimestamp(e.timestamp),\n command: e.command,\n app: e.app || \"-\",\n success: e.success !== undefined ? String(e.success) : \"-\",\n durationMs: e.durationMs ?? \"-\",\n }));\n await maybePaginate(formatOutput(rows, format));\n } else {\n await maybePaginate(formatOutput(events, format));\n }\n });\n\n audit\n .command(\"search <query>\")\n .description(\"Search audit events by keyword\")\n .action(async (query: string) => {\n const config = await loadConfig();\n const format = getOutputFormat(program, config);\n initAudit(getConfigDir());\n\n const events = await searchAuditEvents(query);\n if (events.length === 0 && format !== \"json\") {\n console.log(`No audit events matching \"${query}\".`);\n return;\n }\n if (format !== \"json\") {\n const rows = events.map((e) => ({\n timestamp: formatAuditTimestamp(e.timestamp),\n command: e.command,\n app: e.app || \"-\",\n success: e.success !== undefined ? String(e.success) : \"-\",\n }));\n console.log(formatOutput(rows, format));\n } else {\n console.log(formatOutput(events, format));\n }\n });\n\n audit\n .command(\"clear\")\n .description(\"Clear audit log entries\")\n .option(\"--before <date>\", \"Clear entries before date (ISO 8601)\")\n .option(\"--dry-run\", \"Preview what would be cleared\")\n .action(async (options, cmd: Command) => {\n const dryRun = options.dryRun || isDryRun(cmd);\n await loadConfig();\n initAudit(getConfigDir());\n\n if (!dryRun && !options.before) {\n await requireConfirm(\"Clear all audit log entries?\", program);\n }\n\n const result = await clearAuditLog({\n before: options.before,\n dryRun,\n });\n if (dryRun) {\n console.log(\n `[dry-run] Would delete ${result.deleted} entries, ${result.remaining} would remain.`,\n );\n } else {\n console.log(`Deleted ${result.deleted} entries. ${result.remaining} remaining.`);\n }\n });\n}\n"],"mappings":";;;;;;;;;;;;AACA,SAAS,kBAAkB;AAC3B,SAAS,oBAAoB;AAC7B;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAKP,SAAS,qBAAqB,KAAqB;AACjD,QAAM,OAAO,IAAI,KAAK,GAAG;AACzB,QAAM,MAAM,oBAAI,KAAK;AACrB,QAAM,SAAS,IAAI,QAAQ,IAAI,KAAK,QAAQ;AAC5C,QAAM,UAAU,KAAK,MAAM,SAAS,GAAK;AACzC,MAAI,UAAU,GAAI,QAAO,UAAU,IAAI,aAAa,GAAG,OAAO;AAC9D,QAAM,SAAS,KAAK,MAAM,UAAU,EAAE;AACtC,MAAI,SAAS;AACX,WAAO,GAAG,OAAO,KAAK,SAAS,CAAC,EAAE,SAAS,GAAG,GAAG,CAAC,IAAI,OAAO,KAAK,WAAW,CAAC,EAAE,SAAS,GAAG,GAAG,CAAC,IAAI,OAAO,KAAK,WAAW,CAAC,EAAE,SAAS,GAAG,GAAG,CAAC;AAChJ,QAAM,WAAW,KAAK,MAAM,SAAS,EAAE;AACvC,MAAI,WAAW,GAAG;AAChB,UAAM,OAAO,CAAC,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,KAAK;AAC7D,WAAO,GAAG,KAAK,KAAK,OAAO,CAAC,CAAC,IAAI,OAAO,KAAK,SAAS,CAAC,EAAE,SAAS,GAAG,GAAG,CAAC,IAAI,OAAO,KAAK,WAAW,CAAC,EAAE,SAAS,GAAG,GAAG,CAAC;AAAA,EACzH;AACA,QAAM,SAAS;AAAA,IACb;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACA,SAAO,GAAG,OAAO,KAAK,SAAS,CAAC,CAAC,IAAI,KAAK,QAAQ,CAAC,KAAK,KAAK,YAAY,CAAC;AAC5E;AAEO,SAAS,sBAAsB,SAAwB;AAC5D,QAAM,QAAQ,QAAQ,QAAQ,OAAO,EAAE,YAAY,6BAA6B;AAEhF,QACG,QAAQ,MAAM,EACd,YAAY,0BAA0B,EACtC,OAAO,eAAe,0BAA0B,UAAU,EAAE,EAC5D,OAAO,kBAAkB,mCAAmC,EAC5D,OAAO,oBAAoB,wBAAwB,EACnD,OAAO,OAAO,YAAY;AACzB,UAAM,SAAS,MAAM,WAAW;AAChC,UAAM,SAAS,gBAAgB,SAAS,MAAM;AAC9C,cAAU,aAAa,CAAC;AAExB,UAAM,SAAS,MAAM,gBAAgB;AAAA,MACnC,OAAO,QAAQ;AAAA,MACf,OAAO,QAAQ;AAAA,MACf,SAAS,QAAQ;AAAA,IACnB,CAAC;AACD,QAAI,OAAO,WAAW,KAAK,WAAW,QAAQ;AAC5C,cAAQ,IAAI,wBAAwB;AACpC;AAAA,IACF;AACA,QAAI,WAAW,QAAQ;AACrB,YAAM,OAAO,OAAO,IAAI,CAAC,OAAO;AAAA,QAC9B,WAAW,qBAAqB,EAAE,SAAS;AAAA,QAC3C,SAAS,EAAE;AAAA,QACX,KAAK,EAAE,OAAO;AAAA,QACd,SAAS,EAAE,YAAY,SAAY,OAAO,EAAE,OAAO,IAAI;AAAA,QACvD,YAAY,EAAE,cAAc;AAAA,MAC9B,EAAE;AACF,YAAM,cAAc,aAAa,MAAM,MAAM,CAAC;AAAA,IAChD,OAAO;AACL,YAAM,cAAc,aAAa,QAAQ,MAAM,CAAC;AAAA,IAClD;AAAA,EACF,CAAC;AAEH,QACG,QAAQ,gBAAgB,EACxB,YAAY,gCAAgC,EAC5C,OAAO,OAAO,UAAkB;AAC/B,UAAM,SAAS,MAAM,WAAW;AAChC,UAAM,SAAS,gBAAgB,SAAS,MAAM;AAC9C,cAAU,aAAa,CAAC;AAExB,UAAM,SAAS,MAAM,kBAAkB,KAAK;AAC5C,QAAI,OAAO,WAAW,KAAK,WAAW,QAAQ;AAC5C,cAAQ,IAAI,6BAA6B,KAAK,IAAI;AAClD;AAAA,IACF;AACA,QAAI,WAAW,QAAQ;AACrB,YAAM,OAAO,OAAO,IAAI,CAAC,OAAO;AAAA,QAC9B,WAAW,qBAAqB,EAAE,SAAS;AAAA,QAC3C,SAAS,EAAE;AAAA,QACX,KAAK,EAAE,OAAO;AAAA,QACd,SAAS,EAAE,YAAY,SAAY,OAAO,EAAE,OAAO,IAAI;AAAA,MACzD,EAAE;AACF,cAAQ,IAAI,aAAa,MAAM,MAAM,CAAC;AAAA,IACxC,OAAO;AACL,cAAQ,IAAI,aAAa,QAAQ,MAAM,CAAC;AAAA,IAC1C;AAAA,EACF,CAAC;AAEH,QACG,QAAQ,OAAO,EACf,YAAY,yBAAyB,EACrC,OAAO,mBAAmB,sCAAsC,EAChE,OAAO,aAAa,+BAA+B,EACnD,OAAO,OAAO,SAAS,QAAiB;AACvC,UAAM,SAAS,QAAQ,UAAU,SAAS,GAAG;AAC7C,UAAM,WAAW;AACjB,cAAU,aAAa,CAAC;AAExB,QAAI,CAAC,UAAU,CAAC,QAAQ,QAAQ;AAC9B,YAAM,eAAe,gCAAgC,OAAO;AAAA,IAC9D;AAEA,UAAM,SAAS,MAAM,cAAc;AAAA,MACjC,QAAQ,QAAQ;AAAA,MAChB;AAAA,IACF,CAAC;AACD,QAAI,QAAQ;AACV,cAAQ;AAAA,QACN,0BAA0B,OAAO,OAAO,aAAa,OAAO,SAAS;AAAA,MACvE;AAAA,IACF,OAAO;AACL,cAAQ,IAAI,WAAW,OAAO,OAAO,aAAa,OAAO,SAAS,aAAa;AAAA,IACjF;AAAA,EACF,CAAC;AACL;","names":[]}
@@ -242,30 +242,91 @@ function registerAuthCommands(program) {
242
242
  const token = await authClient.getAccessToken();
243
243
  console.log(token);
244
244
  });
245
- auth.command("setup-gcp").description("Step-by-step guide to create a Google Cloud service account").action(() => {
245
+ auth.command("setup-gcp").description("Step-by-step guide to create a Google Cloud service account").option("--key <path>", "Path to an already-downloaded service account JSON key").action(async (options) => {
246
+ const { existsSync, readFileSync } = await import("fs");
247
+ const { resolve: resolve2 } = await import("path");
246
248
  console.log("\nGPC \u2014 Google Cloud Service Account Setup");
247
- console.log("\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550");
248
- console.log("\nStep 1: Open the Google Cloud Console");
249
- console.log(" https://console.cloud.google.com/iam-admin/serviceaccounts");
250
- console.log("\nStep 2: Create a service account");
251
- console.log(" \u2022 Click 'Create Service Account'");
252
- console.log(" \u2022 Name it: gpc-deploy (or any name you like)");
253
- console.log(" \u2022 Description: GPC Google Play Console access");
254
- console.log("\nStep 3: Grant roles");
255
- console.log(" No GCP roles needed \u2014 permissions are managed in Google Play Console.");
256
- console.log("\nStep 4: Download the JSON key");
257
- console.log(" \u2022 Click your new service account \u2192 Keys \u2192 Add Key \u2192 Create new key \u2192 JSON");
258
- console.log(" \u2022 Save as: ~/gpc-service-account.json");
259
- console.log("\nStep 5: Add to Google Play Console");
260
- console.log(" https://play.google.com/console/developers");
261
- console.log(" \u2022 Users and Permissions \u2192 Invite new users");
262
- console.log(" \u2022 Paste the service account email (ends with @...gserviceaccount.com)");
263
- console.log(" \u2022 Grant: Release manager + View app info + Reply to reviews");
264
- console.log("\nStep 6: Authenticate");
265
- console.log(" gpc auth login --service-account ~/gpc-service-account.json");
266
- console.log("\nStep 7: Verify");
267
- console.log(" gpc doctor");
268
- console.log("\nSee full docs: https://yasserstudio.github.io/gpc/guide/authentication");
249
+ console.log("\u2550".repeat(50));
250
+ let keyPath = options.key;
251
+ if (!keyPath) {
252
+ console.log("\nStep 1: Open the Google Cloud Console");
253
+ console.log(" https://console.cloud.google.com/iam-admin/serviceaccounts");
254
+ console.log("\nStep 2: Create a service account");
255
+ console.log(" \u2022 Click 'Create Service Account'");
256
+ console.log(" \u2022 Name it: gpc-deploy (or any name you like)");
257
+ console.log(" \u2022 Description: GPC Google Play Console access");
258
+ console.log("\nStep 3: Grant roles");
259
+ console.log(" No GCP roles needed \u2014 permissions are managed in Google Play Console.");
260
+ console.log("\nStep 4: Download the JSON key");
261
+ console.log(" \u2022 Click your new service account \u2192 Keys \u2192 Add Key \u2192 Create new key \u2192 JSON");
262
+ console.log(" \u2022 Save as: ~/gpc-service-account.json");
263
+ console.log("\nStep 5: Add to Google Play Console");
264
+ console.log(" https://play.google.com/console/developers");
265
+ console.log(" \u2022 Users and Permissions \u2192 Invite new users");
266
+ console.log(" \u2022 Paste the service account email (ends with @...gserviceaccount.com)");
267
+ console.log(" \u2022 Grant: Release manager + View app info + Reply to reviews");
268
+ const commonPaths = [
269
+ "~/gpc-service-account.json",
270
+ "./service-account.json",
271
+ "./gpc-service-account.json",
272
+ "~/.config/gpc/service-account.json"
273
+ ].map((p) => resolve2(p.replace("~", process.env["HOME"] || "")));
274
+ for (const p of commonPaths) {
275
+ if (existsSync(p)) {
276
+ console.log(`
277
+ \u2713 Found key file: ${p}`);
278
+ keyPath = p;
279
+ break;
280
+ }
281
+ }
282
+ if (!keyPath) {
283
+ console.log("\nOnce you've downloaded the key, run:");
284
+ console.log(" gpc auth setup-gcp --key <path/to/key.json>");
285
+ console.log("\nOr authenticate directly:");
286
+ console.log(" gpc auth login --service-account <path/to/key.json>");
287
+ console.log("\nSee full docs: https://yasserstudio.github.io/gpc/guide/authentication");
288
+ return;
289
+ }
290
+ }
291
+ const absPath = resolve2(keyPath.replace("~", process.env["HOME"] || ""));
292
+ if (!existsSync(absPath)) {
293
+ console.error(`
294
+ \u2717 File not found: ${absPath}`);
295
+ return;
296
+ }
297
+ try {
298
+ const content = JSON.parse(readFileSync(absPath, "utf-8"));
299
+ if (content.type !== "service_account") {
300
+ console.error(`
301
+ \u2717 Not a service account key (type: ${content.type})`);
302
+ return;
303
+ }
304
+ console.log(`
305
+ \u2713 Valid service account key`);
306
+ console.log(` Email: ${content.client_email}`);
307
+ console.log(` Project: ${content.project_id}`);
308
+ } catch {
309
+ console.error(`
310
+ \u2717 Invalid JSON file: ${absPath}`);
311
+ return;
312
+ }
313
+ console.log(`
314
+ Step 6: Authenticating...`);
315
+ try {
316
+ const auth2 = await resolveAuth({ serviceAccountPath: absPath });
317
+ await auth2.getAccessToken();
318
+ const { setConfigValue: setConfigValue2 } = await import("@gpc-cli/config");
319
+ await setConfigValue2("auth.serviceAccount", absPath);
320
+ console.log(`\u2713 Authenticated and saved to config`);
321
+ } catch (err) {
322
+ console.error(`\u2717 Authentication failed: ${err instanceof Error ? err.message : String(err)}`);
323
+ console.log(`
324
+ Try manually: gpc auth login --service-account ${absPath}`);
325
+ return;
326
+ }
327
+ console.log(`
328
+ Step 7: Verifying setup...`);
329
+ console.log(` Run: gpc doctor`);
269
330
  });
270
331
  auth.command("profiles").description("List configured profiles").action(async () => {
271
332
  const { listProfiles } = await import("@gpc-cli/config");
@@ -288,4 +349,4 @@ function registerAuthCommands(program) {
288
349
  export {
289
350
  registerAuthCommands
290
351
  };
291
- //# sourceMappingURL=auth-OTA3SV3J.js.map
352
+ //# sourceMappingURL=auth-BA4FE2PO.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/commands/auth.ts"],"sourcesContent":["import type { Command } from \"commander\";\nimport { createInterface } from \"node:readline\";\nimport { access } from \"node:fs/promises\";\nimport { resolve } from \"node:path\";\nimport { resolveAuth, loadServiceAccountKey, clearTokenCache, AuthError } from \"@gpc-cli/auth\";\nimport { loadConfig, getCacheDir, deleteConfigValue, setConfigValue } from \"@gpc-cli/config\";\nimport { formatOutput } from \"@gpc-cli/core\";\nimport { getOutputFormat } from \"../format.js\";\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nasync function askQuestion(\n rl: ReturnType<typeof createInterface>,\n question: string,\n): Promise<string> {\n return new Promise((resolve) => {\n rl.question(question, (answer) => resolve(answer.trim()));\n });\n}\n\n/** Resolve a path to absolute (prevents CWD-dependent config). */\nfunction toAbsolutePath(pathStr: string): string {\n return resolve(pathStr);\n}\n\n/** Verify that the saved credentials can acquire a token. */\nasync function verifyToken(serviceAccountPath?: string): Promise<{ email: string; ok: boolean; error?: string }> {\n try {\n const client = await resolveAuth({ serviceAccountPath });\n const email = client.getClientEmail();\n await client.getAccessToken();\n return { email, ok: true };\n } catch (err) {\n const email = \"unknown\";\n const msg = err instanceof Error ? err.message : String(err);\n return { email, ok: false, error: msg };\n }\n}\n\n// ---------------------------------------------------------------------------\n// Interactive login wizard\n// ---------------------------------------------------------------------------\n\nasync function runLoginWizard(program: Command): Promise<void> {\n const rl = createInterface({ input: process.stdin, output: process.stdout });\n\n try {\n console.log(\"\\nGPC Authentication Setup\");\n console.log(\"\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\");\n\n // Step 1: auth method\n console.log(\"\\nAuthentication methods:\");\n console.log(\" 1. Service account key file (recommended)\");\n console.log(\" 2. Application Default Credentials (ADC)\");\n const method = await askQuestion(rl, \"\\nSelect method [1]: \");\n const useAdc = method === \"2\";\n\n if (useAdc) {\n const client = await resolveAuth();\n const email = client.getClientEmail();\n // Verify token works\n await client.getAccessToken();\n outputLoginResult(program, { account: email, method: \"adc\", verified: true });\n return;\n }\n\n // Step 2: credentials path with validation loop\n let saPath = \"\";\n while (!saPath) {\n const input = await askQuestion(rl, \"\\nPath to service account JSON key: \");\n if (!input) {\n console.log(\" Path is required.\");\n continue;\n }\n try {\n await access(input);\n saPath = toAbsolutePath(input);\n } catch {\n console.log(` File not found: ${input}`);\n }\n }\n\n // Step 3: optional profile name\n const profileName = await askQuestion(rl, \"\\nProfile name (optional, press Enter to skip): \");\n\n // Step 4: default package name\n const packageName = await askQuestion(\n rl,\n \"Default package name (optional, e.g. com.example.app): \",\n );\n\n // Apply settings\n const key = await loadServiceAccountKey(saPath);\n\n if (profileName) {\n const { setProfileConfig } = await import(\"@gpc-cli/config\");\n await setProfileConfig(profileName, {\n auth: { serviceAccount: saPath },\n ...(packageName && { app: packageName }),\n });\n } else {\n await setConfigValue(\"auth.serviceAccount\", saPath);\n if (packageName) await setConfigValue(\"app\", packageName);\n }\n\n // Verify token\n const verification = await verifyToken(saPath);\n\n outputLoginResult(program, {\n account: key.client_email,\n project: key.project_id,\n method: \"service-account\",\n profile: profileName || undefined,\n verified: verification.ok,\n verifyError: verification.error,\n });\n } finally {\n rl.close();\n }\n}\n\n// ---------------------------------------------------------------------------\n// Structured login output\n// ---------------------------------------------------------------------------\n\ninterface LoginResult {\n account: string;\n project?: string;\n method: string;\n profile?: string;\n verified: boolean;\n verifyError?: string;\n}\n\nfunction outputLoginResult(program: Command, result: LoginResult): void {\n const parentOpts = program.opts() ?? {};\n const jsonMode = !!(parentOpts[\"json\"] || parentOpts[\"output\"] === \"json\");\n\n if (jsonMode) {\n console.log(\n JSON.stringify({\n success: true,\n account: result.account,\n project: result.project,\n method: result.method,\n profile: result.profile,\n verified: result.verified,\n ...(result.verifyError && { verifyError: result.verifyError }),\n }),\n );\n return;\n }\n\n if (result.profile) {\n console.log(`\\nProfile \"${result.profile}\" configured with ${result.account}`);\n } else if (result.method === \"adc\") {\n console.log(`\\nAuthenticated via Application Default Credentials`);\n console.log(`Account: ${result.account}`);\n } else {\n console.log(`\\nAuthenticated as ${result.account}`);\n }\n if (result.project) console.log(`Project: ${result.project}`);\n\n if (result.verified) {\n console.log(\"Verified: token acquired successfully\");\n } else if (result.verifyError) {\n console.log(`Warning: token verification failed: ${result.verifyError}`);\n console.log(\"Credentials saved, but check your setup with: gpc doctor\");\n }\n\n if (!result.verifyError) {\n console.log(\"\\nRun 'gpc doctor' to verify your full setup.\");\n }\n}\n\n// ---------------------------------------------------------------------------\n// Command registration\n// ---------------------------------------------------------------------------\n\nexport function registerAuthCommands(program: Command): void {\n const auth = program.command(\"auth\").description(\"Manage authentication\");\n\n auth\n .command(\"login\")\n .description(\"Authenticate with Google Play Developer API\")\n .option(\"--service-account <path>\", \"Path to service account JSON key file\")\n .option(\"--adc\", \"Use Application Default Credentials\")\n .option(\"--profile <name>\", \"Store credentials under a named profile\")\n .action(async (options: { serviceAccount?: string; adc?: boolean; profile?: string }) => {\n if (options.serviceAccount) {\n const absolutePath = toAbsolutePath(options.serviceAccount);\n const key = await loadServiceAccountKey(absolutePath);\n\n if (options.profile) {\n const { setProfileConfig } = await import(\"@gpc-cli/config\");\n await setProfileConfig(options.profile, {\n auth: { serviceAccount: absolutePath },\n });\n } else {\n await setConfigValue(\"auth.serviceAccount\", absolutePath);\n }\n\n // Verify token works\n const verification = await verifyToken(absolutePath);\n\n outputLoginResult(program, {\n account: key.client_email,\n project: key.project_id,\n method: \"service-account\",\n profile: options.profile,\n verified: verification.ok,\n verifyError: verification.error,\n });\n } else if (options.adc) {\n const client = await resolveAuth();\n const email = client.getClientEmail();\n await client.getAccessToken();\n outputLoginResult(program, { account: email, method: \"adc\", verified: true });\n } else {\n // Interactive wizard when no flags provided and in interactive mode\n const opts = program.opts();\n const interactive =\n opts[\"interactive\"] !== false && opts[\"ci\"] !== true && process.stdin.isTTY;\n if (interactive) {\n await runLoginWizard(program);\n } else {\n console.log(\"Usage: gpc auth login --service-account <path>\");\n console.log(\"\");\n console.log(\"Authentication methods:\");\n console.log(\" --service-account <path> Service account JSON key file\");\n console.log(\" --adc Application Default Credentials\");\n console.log(\"\");\n console.log(\"Options:\");\n console.log(\" --profile <name> Store under a named profile\");\n }\n }\n });\n\n auth\n .command(\"status\")\n .description(\"Show current authentication status\")\n .action(async () => {\n const config = await loadConfig();\n const format = getOutputFormat(program, config);\n try {\n const client = await resolveAuth({\n serviceAccountPath: config.auth?.serviceAccount,\n cachePath: getCacheDir(),\n });\n const data = {\n authenticated: true,\n account: client.getClientEmail(),\n project: client.getProjectId(),\n ...(config.profile && { profile: config.profile }),\n };\n console.log(formatOutput(data, format));\n } catch (error) {\n if (error instanceof AuthError) {\n const data = {\n authenticated: false,\n error: error.message,\n suggestion: error.suggestion,\n };\n console.log(formatOutput(data, format));\n }\n throw error; // Let error handler set exit code 3\n }\n });\n\n auth\n .command(\"logout\")\n .description(\"Clear stored credentials and token cache\")\n .option(\"--profile <name>\", \"Clear credentials for a specific profile\")\n .action(async (options: { profile?: string }) => {\n if (options.profile) {\n const { deleteProfile } = await import(\"@gpc-cli/config\");\n const deleted = await deleteProfile(options.profile);\n if (deleted) {\n console.log(`Profile \"${options.profile}\" removed.`);\n } else {\n console.log(`Profile \"${options.profile}\" not found.`);\n }\n } else {\n await deleteConfigValue(\"auth.serviceAccount\");\n console.log(\"Credentials cleared.\");\n }\n await clearTokenCache(getCacheDir());\n console.log(\"Token cache cleared.\");\n });\n\n auth\n .command(\"whoami\")\n .description(\"Show current authenticated identity\")\n .action(async () => {\n const config = await loadConfig();\n const client = await resolveAuth({\n serviceAccountPath: config.auth?.serviceAccount,\n cachePath: getCacheDir(),\n });\n console.log(client.getClientEmail());\n });\n\n auth\n .command(\"switch <profile>\")\n .description(\"Switch to a named profile\")\n .action(async (profile: string) => {\n // loadConfig with the profile will throw ConfigError if profile doesn't exist\n const config = await loadConfig({ profile });\n await setConfigValue(\"profile\", profile);\n console.log(`Switched to profile \"${profile}\"`);\n if (config.auth?.serviceAccount) {\n console.log(`Service account: ${config.auth.serviceAccount}`);\n }\n });\n\n auth\n .command(\"token\")\n .description(\"Print the current access token (useful for manual API calls)\")\n .action(async () => {\n const config = await loadConfig();\n const authClient = await resolveAuth({\n serviceAccountPath: config.auth?.serviceAccount,\n cachePath: getCacheDir(),\n });\n const token = await authClient.getAccessToken();\n console.log(token);\n });\n\n auth\n .command(\"setup-gcp\")\n .description(\"Step-by-step guide to create a Google Cloud service account\")\n .option(\"--key <path>\", \"Path to an already-downloaded service account JSON key\")\n .action(async (options: { key?: string }) => {\n const { existsSync, readFileSync } = await import(\"node:fs\");\n const { resolve } = await import(\"node:path\");\n\n console.log(\"\\nGPC \\u2014 Google Cloud Service Account Setup\");\n console.log(\"\\u2550\".repeat(50));\n\n // If key path provided or user already has one, skip to validation\n let keyPath = options.key;\n\n if (!keyPath) {\n console.log(\"\\nStep 1: Open the Google Cloud Console\");\n console.log(\" https://console.cloud.google.com/iam-admin/serviceaccounts\");\n console.log(\"\\nStep 2: Create a service account\");\n console.log(\" \\u2022 Click 'Create Service Account'\");\n console.log(\" \\u2022 Name it: gpc-deploy (or any name you like)\");\n console.log(\" \\u2022 Description: GPC Google Play Console access\");\n console.log(\"\\nStep 3: Grant roles\");\n console.log(\" No GCP roles needed \\u2014 permissions are managed in Google Play Console.\");\n console.log(\"\\nStep 4: Download the JSON key\");\n console.log(\" \\u2022 Click your new service account \\u2192 Keys \\u2192 Add Key \\u2192 Create new key \\u2192 JSON\");\n console.log(\" \\u2022 Save as: ~/gpc-service-account.json\");\n console.log(\"\\nStep 5: Add to Google Play Console\");\n console.log(\" https://play.google.com/console/developers\");\n console.log(\" \\u2022 Users and Permissions \\u2192 Invite new users\");\n console.log(\" \\u2022 Paste the service account email (ends with @...gserviceaccount.com)\");\n console.log(\" \\u2022 Grant: Release manager + View app info + Reply to reviews\");\n\n // Try to auto-detect a key file\n const commonPaths = [\n \"~/gpc-service-account.json\",\n \"./service-account.json\",\n \"./gpc-service-account.json\",\n \"~/.config/gpc/service-account.json\",\n ].map((p) => resolve(p.replace(\"~\", process.env[\"HOME\"] || \"\")));\n\n for (const p of commonPaths) {\n if (existsSync(p)) {\n console.log(`\\n\\u2713 Found key file: ${p}`);\n keyPath = p;\n break;\n }\n }\n\n if (!keyPath) {\n console.log(\"\\nOnce you've downloaded the key, run:\");\n console.log(\" gpc auth setup-gcp --key <path/to/key.json>\");\n console.log(\"\\nOr authenticate directly:\");\n console.log(\" gpc auth login --service-account <path/to/key.json>\");\n console.log(\"\\nSee full docs: https://yasserstudio.github.io/gpc/guide/authentication\");\n return;\n }\n }\n\n // Validate the key file\n const absPath = resolve(keyPath.replace(\"~\", process.env[\"HOME\"] || \"\"));\n if (!existsSync(absPath)) {\n console.error(`\\n\\u2717 File not found: ${absPath}`);\n return;\n }\n\n try {\n const content = JSON.parse(readFileSync(absPath, \"utf-8\"));\n if (content.type !== \"service_account\") {\n console.error(`\\n\\u2717 Not a service account key (type: ${content.type})`);\n return;\n }\n console.log(`\\n\\u2713 Valid service account key`);\n console.log(` Email: ${content.client_email}`);\n console.log(` Project: ${content.project_id}`);\n } catch {\n console.error(`\\n\\u2717 Invalid JSON file: ${absPath}`);\n return;\n }\n\n // Auto-login\n console.log(`\\nStep 6: Authenticating...`);\n try {\n const auth = await resolveAuth({ serviceAccountPath: absPath });\n await auth.getAccessToken();\n const { setConfigValue } = await import(\"@gpc-cli/config\");\n await setConfigValue(\"auth.serviceAccount\", absPath);\n console.log(`\\u2713 Authenticated and saved to config`);\n } catch (err) {\n console.error(`\\u2717 Authentication failed: ${err instanceof Error ? err.message : String(err)}`);\n console.log(`\\nTry manually: gpc auth login --service-account ${absPath}`);\n return;\n }\n\n // Auto-run doctor\n console.log(`\\nStep 7: Verifying setup...`);\n console.log(` Run: gpc doctor`);\n });\n\n auth\n .command(\"profiles\")\n .description(\"List configured profiles\")\n .action(async () => {\n const { listProfiles } = await import(\"@gpc-cli/config\");\n const config = await loadConfig();\n const profiles = await listProfiles();\n const format = getOutputFormat(program, config);\n\n if (profiles.length === 0) {\n console.log(\n \"No profiles configured. Use: gpc auth login --service-account <path> --profile <name>\",\n );\n return;\n }\n\n const data = profiles.map((name) => ({\n name,\n active: name === config.profile,\n }));\n console.log(formatOutput(data, format));\n });\n}\n"],"mappings":"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","names":["resolve","auth","setConfigValue"]}
package/dist/bin.js CHANGED
@@ -3,7 +3,7 @@ import {
3
3
  createProgram,
4
4
  handleCliError,
5
5
  loadPlugins
6
- } from "./chunk-WWVURXVO.js";
6
+ } from "./chunk-7A4IKNZ5.js";
7
7
  import {
8
8
  checkForUpdate,
9
9
  formatUpdateNotification
@@ -46,7 +46,7 @@ if (!_isJsonMode && !_isQuiet && !_isSetupCommand && !existsSync(getUserConfigPa
46
46
  }
47
47
  await setupNetworking();
48
48
  initAudit(getConfigDir());
49
- var currentVersion = "0.9.47";
49
+ var currentVersion = "0.9.49";
50
50
  var isUpdateCommand = process.argv[2] === "update";
51
51
  var updateCheckPromise = isUpdateCommand ? Promise.resolve(null) : checkForUpdate(currentVersion);
52
52
  if (process.argv.includes("--ci")) {
@@ -67,19 +67,19 @@ function registerPluginCommands(program, manager) {
67
67
  import { Command } from "commander";
68
68
  async function createProgram(pluginManager) {
69
69
  const program = new Command();
70
- program.name("gpc").description("GPC \u2014 Google Play Console CLI").version("0.9.47", "-V, --version").option("-o, --output <format>", "Output format: table, json, yaml, markdown, junit").option("-v, --verbose", "Enable debug logging").option("-q, --quiet", "Suppress non-essential output").option("-a, --app <package>", "App package name").option("-p, --profile <name>", "Auth profile name").option("--no-color", "Disable colored output").option("--no-interactive", "Disable interactive prompts").option("-y, --yes", "Skip confirmation prompts").option("--dry-run", "Preview changes without executing").option("--notify [target]", "Send webhook notification on completion (slack, discord, custom)").option("--ci", "Force CI mode (JSON output, no prompts, strict exit codes)").option("-j, --json", "Shorthand for --output json").option("--apps <csv>", "Comma-separated package names for multi-app operations").showSuggestionAfterError(false);
70
+ program.name("gpc").description("GPC \u2014 Google Play Console CLI").version("0.9.49", "-V, --version").option("-o, --output <format>", "Output format: table, json, yaml, markdown, junit").option("-v, --verbose", "Enable debug logging").option("-q, --quiet", "Suppress non-essential output").option("-a, --app <package>", "App package name").option("-p, --profile <name>", "Auth profile name").option("--no-color", "Disable colored output").option("--no-interactive", "Disable interactive prompts").option("-y, --yes", "Skip confirmation prompts").option("--dry-run", "Preview changes without executing").option("--notify [target]", "Send webhook notification on completion (slack, discord, custom)").option("--ci", "Force CI mode (JSON output, no prompts, strict exit codes)").option("-j, --json", "Shorthand for --output json").option("--apps <csv>", "Comma-separated package names for multi-app operations").showSuggestionAfterError(false);
71
71
  const commandLoaders = {
72
72
  auth: async () => {
73
- (await import("./auth-OTA3SV3J.js")).registerAuthCommands(program);
73
+ (await import("./auth-BA4FE2PO.js")).registerAuthCommands(program);
74
74
  },
75
75
  config: async () => {
76
- (await import("./config-NY3TZGVS.js")).registerConfigCommands(program);
76
+ (await import("./config-JOYJ7TQC.js")).registerConfigCommands(program);
77
77
  },
78
78
  doctor: async () => {
79
- (await import("./doctor-QCCWG6Y3.js")).registerDoctorCommand(program);
79
+ (await import("./doctor-Q4WI432G.js")).registerDoctorCommand(program);
80
80
  },
81
81
  update: async () => {
82
- (await import("./update-XAO5EZHC.js")).registerUpdateCommand(program);
82
+ (await import("./update-QSRQBFDJ.js")).registerUpdateCommand(program);
83
83
  },
84
84
  docs: async () => {
85
85
  (await import("./docs-4D2SJ4LY.js")).registerDocsCommand(program);
@@ -94,13 +94,13 @@ async function createProgram(pluginManager) {
94
94
  (await import("./apps-FKD3ZG5X.js")).registerAppsCommands(program);
95
95
  },
96
96
  releases: async () => {
97
- (await import("./releases-276W3BR7.js")).registerReleasesCommands(program);
97
+ (await import("./releases-OUJ65774.js")).registerReleasesCommands(program);
98
98
  },
99
99
  tracks: async () => {
100
- (await import("./tracks-YHMO2A6B.js")).registerTracksCommands(program);
100
+ (await import("./tracks-DO7C5OSE.js")).registerTracksCommands(program);
101
101
  },
102
102
  status: async () => {
103
- (await import("./status-6LH5W4FU.js")).registerStatusCommand(program);
103
+ (await import("./status-3HXBBXG6.js")).registerStatusCommand(program);
104
104
  },
105
105
  listings: async () => {
106
106
  (await import("./listings-7SGQ4SRX.js")).registerListingsCommands(program);
@@ -112,13 +112,13 @@ async function createProgram(pluginManager) {
112
112
  (await import("./vitals-PJEQUUAK.js")).registerVitalsCommands(program);
113
113
  },
114
114
  subscriptions: async () => {
115
- (await import("./subscriptions-DZP3Y7O7.js")).registerSubscriptionsCommands(program);
115
+ (await import("./subscriptions-LURZFPGJ.js")).registerSubscriptionsCommands(program);
116
116
  },
117
117
  iap: async () => {
118
118
  (await import("./iap-OUI5YYN4.js")).registerIapCommands(program);
119
119
  },
120
120
  purchases: async () => {
121
- (await import("./purchases-Z3QBM3UO.js")).registerPurchasesCommands(program);
121
+ (await import("./purchases-UBFLNYZC.js")).registerPurchasesCommands(program);
122
122
  },
123
123
  pricing: async () => {
124
124
  (await import("./pricing-JJZFICFL.js")).registerPricingCommands(program);
@@ -168,7 +168,7 @@ async function createProgram(pluginManager) {
168
168
  (await import("./bundle-F7MUVC5J.js")).registerBundleCommands(program);
169
169
  },
170
170
  audit: async () => {
171
- (await import("./audit-JASSHRWN.js")).registerAuditCommands(program);
171
+ (await import("./audit-VTWXTXC6.js")).registerAuditCommands(program);
172
172
  },
173
173
  migrate: async () => {
174
174
  (await import("./migrate-ZQCJGQQS.js")).registerMigrateCommands(program);
@@ -177,16 +177,19 @@ async function createProgram(pluginManager) {
177
177
  (await import("./anomalies-V3AFS4LD.js")).registerAnomaliesCommands(program);
178
178
  },
179
179
  "install-skills": async () => {
180
- (await import("./install-skills-6QDUXI5F.js")).registerInstallSkillsCommand(program);
180
+ (await import("./install-skills-JKPYZHYS.js")).registerInstallSkillsCommand(program);
181
+ },
182
+ verify: async () => {
183
+ (await import("./verify-UUQNQMPG.js")).registerVerifyCommand(program);
181
184
  },
182
185
  version: async () => {
183
- (await import("./version-R3P4NHCF.js")).registerVersionCommand(program);
186
+ (await import("./version-V2OQLSVG.js")).registerVersionCommand(program);
184
187
  },
185
188
  cache: async () => {
186
189
  (await import("./cache-XKPLZYEB.js")).registerCacheCommand(program);
187
190
  },
188
191
  feedback: async () => {
189
- (await import("./feedback-CET2X67K.js")).registerFeedbackCommand(program);
192
+ (await import("./feedback-3JAMSICL.js")).registerFeedbackCommand(program);
190
193
  },
191
194
  quickstart: async () => {
192
195
  (await import("./quickstart-Z5Y3FYJU.js")).registerQuickstartCommand(program);
@@ -213,7 +216,7 @@ async function createProgram(pluginManager) {
213
216
  (await import("./init-WSTQTJOD.js")).registerInitCommand(program);
214
217
  },
215
218
  preflight: async () => {
216
- (await import("./preflight-N7ZRG2JI.js")).registerPreflightCommand(program);
219
+ (await import("./preflight-W3JAJ4GO.js")).registerPreflightCommand(program);
217
220
  },
218
221
  plugins: async () => {
219
222
  registerPluginsCommand(program, pluginManager);
@@ -454,4 +457,4 @@ export {
454
457
  createProgram,
455
458
  handleCliError
456
459
  };
457
- //# sourceMappingURL=chunk-WWVURXVO.js.map
460
+ //# sourceMappingURL=chunk-7A4IKNZ5.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/plugins.ts","../src/program.ts","../src/error-handler.ts"],"sourcesContent":["import { PluginManager, discoverPlugins } from \"@gpc-cli/core\";\nimport type { Command } from \"commander\";\n\n/**\n * Load and initialize all plugins.\n * First-party plugins (@gpc-cli/*) are auto-trusted.\n * Third-party plugins require prior approval stored in config.\n * Plugin loading is disabled in standalone binary mode.\n */\nexport async function loadPlugins(): Promise<PluginManager> {\n const manager = new PluginManager();\n\n // Standalone binary cannot resolve external npm packages at runtime\n if (process.env[\"__GPC_BINARY\"] === \"1\") {\n return manager;\n }\n\n try {\n const { loadConfig } = await import(\"@gpc-cli/config\");\n const config = await loadConfig();\n const plugins = await discoverPlugins({ configPlugins: config.plugins });\n const approved = new Set(config.approvedPlugins ?? []);\n\n for (const plugin of plugins) {\n const isTrusted = plugin.name.startsWith(\"@gpc-cli/\");\n\n if (!isTrusted && !approved.has(plugin.name)) {\n // Skip unapproved third-party plugins silently in non-interactive mode\n // In interactive mode, the user would run `gpc plugins approve <name>` first\n const isQuiet = process.argv.includes(\"--quiet\") || process.argv.includes(\"-q\");\n if (!isQuiet) {\n console.error(\n `Plugin \"${plugin.name}\" is not approved. Run: gpc plugins approve ${plugin.name}`,\n );\n }\n continue;\n }\n\n try {\n await manager.load(plugin);\n } catch {\n // Skip plugins that fail to load — don't block the CLI\n }\n }\n } catch {\n // Config loading failure shouldn't block plugin-free commands\n }\n\n return manager;\n}\n\n/**\n * Register plugin-defined commands with the Commander program.\n */\nexport function registerPluginCommands(program: Command, manager: PluginManager): void {\n for (const def of manager.getRegisteredCommands()) {\n const cmd = program.command(def.name).description(def.description);\n\n if (def.arguments) {\n for (const arg of def.arguments) {\n const syntax = arg.required ? `<${arg.name}>` : `[${arg.name}]`;\n cmd.argument(syntax, arg.description);\n }\n }\n\n if (def.options) {\n for (const opt of def.options) {\n cmd.option(\n opt.flags,\n opt.description,\n opt.defaultValue as string | boolean | string[] | undefined,\n );\n }\n }\n\n cmd.action(async (...rawArgs: unknown[]) => {\n const opts = rawArgs[rawArgs.length - 2] as Record<string, unknown>;\n const args: Record<string, unknown> = {};\n\n if (def.arguments) {\n def.arguments.forEach((argDef, i) => {\n args[argDef.name] = rawArgs[i];\n });\n }\n\n await def.action(args, opts);\n });\n }\n}\n","import { Command } from \"commander\";\nimport type { PluginManager } from \"@gpc-cli/core\";\nimport type { CommandEvent, CommandResult } from \"@gpc-cli/plugin-sdk\";\nimport { registerPluginCommands } from \"./plugins.js\";\n\nexport async function createProgram(pluginManager?: PluginManager): Promise<Command> {\n const program = new Command();\n\n program\n .name(\"gpc\")\n .description(\"GPC — Google Play Console CLI\")\n .version(process.env[\"__GPC_VERSION\"] || \"0.0.0\", \"-V, --version\")\n .option(\"-o, --output <format>\", \"Output format: table, json, yaml, markdown, junit\")\n .option(\"-v, --verbose\", \"Enable debug logging\")\n .option(\"-q, --quiet\", \"Suppress non-essential output\")\n .option(\"-a, --app <package>\", \"App package name\")\n .option(\"-p, --profile <name>\", \"Auth profile name\")\n .option(\"--no-color\", \"Disable colored output\")\n .option(\"--no-interactive\", \"Disable interactive prompts\")\n .option(\"-y, --yes\", \"Skip confirmation prompts\")\n .option(\"--dry-run\", \"Preview changes without executing\")\n .option(\"--notify [target]\", \"Send webhook notification on completion (slack, discord, custom)\")\n .option(\"--ci\", \"Force CI mode (JSON output, no prompts, strict exit codes)\")\n .option(\"-j, --json\", \"Shorthand for --output json\")\n .option(\"--apps <csv>\", \"Comma-separated package names for multi-app operations\")\n .showSuggestionAfterError(false);\n\n const commandLoaders: Record<string, () => Promise<void>> = {\n auth: async () => {\n (await import(\"./commands/auth.js\")).registerAuthCommands(program);\n },\n config: async () => {\n (await import(\"./commands/config.js\")).registerConfigCommands(program);\n },\n doctor: async () => {\n (await import(\"./commands/doctor.js\")).registerDoctorCommand(program);\n },\n update: async () => {\n (await import(\"./commands/update.js\")).registerUpdateCommand(program);\n },\n docs: async () => {\n (await import(\"./commands/docs.js\")).registerDocsCommand(program);\n },\n changelog: async () => {\n (await import(\"./commands/changelog.js\")).registerChangelogCommand(program);\n },\n completion: async () => {\n (await import(\"./commands/completion.js\")).registerCompletionCommand(program);\n },\n apps: async () => {\n (await import(\"./commands/apps.js\")).registerAppsCommands(program);\n },\n releases: async () => {\n (await import(\"./commands/releases.js\")).registerReleasesCommands(program);\n },\n tracks: async () => {\n (await import(\"./commands/tracks.js\")).registerTracksCommands(program);\n },\n status: async () => {\n (await import(\"./commands/status.js\")).registerStatusCommand(program);\n },\n listings: async () => {\n (await import(\"./commands/listings.js\")).registerListingsCommands(program);\n },\n reviews: async () => {\n (await import(\"./commands/reviews.js\")).registerReviewsCommands(program);\n },\n vitals: async () => {\n (await import(\"./commands/vitals.js\")).registerVitalsCommands(program);\n },\n subscriptions: async () => {\n (await import(\"./commands/subscriptions.js\")).registerSubscriptionsCommands(program);\n },\n iap: async () => {\n (await import(\"./commands/iap.js\")).registerIapCommands(program);\n },\n purchases: async () => {\n (await import(\"./commands/purchases.js\")).registerPurchasesCommands(program);\n },\n pricing: async () => {\n (await import(\"./commands/pricing.js\")).registerPricingCommands(program);\n },\n reports: async () => {\n (await import(\"./commands/reports.js\")).registerReportsCommands(program);\n },\n users: async () => {\n (await import(\"./commands/users.js\")).registerUsersCommands(program);\n },\n testers: async () => {\n (await import(\"./commands/testers.js\")).registerTestersCommands(program);\n },\n validate: async () => {\n (await import(\"./commands/validate.js\")).registerValidateCommand(program);\n },\n publish: async () => {\n (await import(\"./commands/publish.js\")).registerPublishCommand(program);\n },\n recovery: async () => {\n (await import(\"./commands/recovery.js\")).registerRecoveryCommands(program);\n },\n \"data-safety\": async () => {\n (await import(\"./commands/data-safety.js\")).registerDataSafetyCommands(program);\n },\n \"external-transactions\": async () => {\n (await import(\"./commands/external-transactions.js\")).registerExternalTransactionsCommands(\n program,\n );\n },\n \"device-tiers\": async () => {\n (await import(\"./commands/device-tiers.js\")).registerDeviceTiersCommands(program);\n },\n \"one-time-products\": async () => {\n (await import(\"./commands/one-time-products.js\")).registerOneTimeProductsCommands(program);\n },\n \"internal-sharing\": async () => {\n (await import(\"./commands/internal-sharing.js\")).registerInternalSharingCommands(program);\n },\n \"generated-apks\": async () => {\n (await import(\"./commands/generated-apks.js\")).registerGeneratedApksCommands(program);\n },\n \"purchase-options\": async () => {\n (await import(\"./commands/purchase-options.js\")).registerPurchaseOptionsCommands(program);\n },\n bundle: async () => {\n (await import(\"./commands/bundle.js\")).registerBundleCommands(program);\n },\n audit: async () => {\n (await import(\"./commands/audit.js\")).registerAuditCommands(program);\n },\n migrate: async () => {\n (await import(\"./commands/migrate.js\")).registerMigrateCommands(program);\n },\n anomalies: async () => {\n (await import(\"./commands/anomalies.js\")).registerAnomaliesCommands(program);\n },\n \"install-skills\": async () => {\n (await import(\"./commands/install-skills.js\")).registerInstallSkillsCommand(program);\n },\n verify: async () => {\n (await import(\"./commands/verify.js\")).registerVerifyCommand(program);\n },\n version: async () => {\n (await import(\"./commands/version.js\")).registerVersionCommand(program);\n },\n cache: async () => {\n (await import(\"./commands/cache.js\")).registerCacheCommand(program);\n },\n feedback: async () => {\n (await import(\"./commands/feedback.js\")).registerFeedbackCommand(program);\n },\n quickstart: async () => {\n (await import(\"./commands/quickstart.js\")).registerQuickstartCommand(program);\n },\n grants: async () => {\n (await import(\"./commands/grants.js\")).registerGrantsCommands(program);\n },\n train: async () => {\n (await import(\"./commands/train.js\")).registerTrainCommands(program);\n },\n quota: async () => {\n (await import(\"./commands/quota.js\")).registerQuotaCommand(program);\n },\n games: async () => {\n (await import(\"./commands/games.js\")).registerGamesCommands(program);\n },\n enterprise: async () => {\n (await import(\"./commands/enterprise.js\")).registerEnterpriseCommands(program);\n },\n diff: async () => {\n (await import(\"./commands/diff.js\")).registerDiffCommand(program);\n },\n init: async () => {\n (await import(\"./commands/init.js\")).registerInitCommand(program);\n },\n preflight: async () => {\n (await import(\"./commands/preflight.js\")).registerPreflightCommand(program);\n },\n plugins: async () => {\n registerPluginsCommand(program, pluginManager);\n },\n rtdn: async () => {\n (await import(\"./commands/rtdn.js\")).registerRtdnCommands(program);\n },\n };\n\n // \"Did you mean?\" suggestions for unknown commands\n function levenshtein(a: string, b: string): number {\n const m = a.length,\n n = b.length;\n const dp: number[][] = Array.from({ length: m + 1 }, (_, i) =>\n Array.from({ length: n + 1 }, (_, j) => (i === 0 ? j : j === 0 ? i : 0)),\n );\n const cell = (r: number, c: number): number => dp[r]?.[c] ?? 0;\n for (let i = 1; i <= m; i++) {\n for (let j = 1; j <= n; j++) {\n (dp[i] as number[])[j] =\n a[i - 1] === b[j - 1]\n ? cell(i - 1, j - 1)\n : 1 + Math.min(cell(i - 1, j), cell(i, j - 1), cell(i - 1, j - 1));\n }\n }\n return cell(m, n);\n }\n\n program.on(\"command:*\", (operands: string[]) => {\n const cmd = operands[0] ?? \"\";\n const names = Object.keys(commandLoaders);\n const best = names\n .map((name) => ({ name, d: levenshtein(cmd, name) }))\n .sort((a, b) => a.d - b.d)[0];\n console.error(`Error: Unknown command \"${cmd}\".`);\n if (best && best.d <= 3) console.error(`Did you mean: gpc ${best.name}?`);\n console.error(`Run \"gpc --help\" to see all commands.`);\n process.exit(2);\n });\n\n // Resolve command aliases for lazy loading\n const commandAliases: Record<string, string> = {\n \"ext-txn\": \"external-transactions\",\n otp: \"one-time-products\",\n };\n\n const rawTarget = process.argv[2];\n const target = rawTarget ? (commandAliases[rawTarget] ?? rawTarget) : undefined;\n\n const loader = target ? commandLoaders[target] : undefined;\n if (loader) {\n await loader();\n } else {\n await Promise.all(Object.values(commandLoaders).map((loader) => loader()));\n }\n\n // Register plugin-defined commands\n if (pluginManager) {\n registerPluginCommands(program, pluginManager);\n }\n\n // Wire plugin lifecycle hooks around command execution\n if (pluginManager) {\n wrapCommandHooks(program, pluginManager);\n }\n\n return program;\n}\n\n/**\n * `gpc plugins` — manage plugins.\n */\nfunction registerPluginsCommand(program: Command, manager?: PluginManager): void {\n const cmd = program.command(\"plugins\").description(\"Manage plugins\");\n\n cmd\n .command(\"list\")\n .description(\"List loaded plugins\")\n .action(() => {\n const plugins = manager?.getLoadedPlugins() ?? [];\n const opts = program.opts();\n\n if (opts[\"output\"] === \"json\") {\n console.log(JSON.stringify(plugins, null, 2));\n return;\n }\n\n if (plugins.length === 0) {\n console.log(\"No plugins loaded.\");\n console.log('\\nConfigure plugins in .gpcrc.json: { \"plugins\": [\"@gpc-cli/plugin-ci\"] }');\n return;\n }\n\n console.log(\"Loaded plugins:\\n\");\n for (const p of plugins) {\n const trust = p.trusted ? \"trusted\" : \"third-party\";\n console.log(` ${p.name}@${p.version} (${trust})`);\n }\n\n const commands = manager?.getRegisteredCommands() ?? [];\n if (commands.length > 0) {\n console.log(\"\\nPlugin commands:\\n\");\n for (const c of commands) {\n console.log(` gpc ${c.name} — ${c.description}`);\n }\n }\n });\n\n cmd\n .command(\"init <name>\")\n .description(\"Scaffold a new plugin project\")\n .option(\"-d, --dir <path>\", \"Output directory (defaults to ./gpc-plugin-<name>)\")\n .option(\"--description <text>\", \"Plugin description\")\n .action(async (name: string, opts: { dir?: string; description?: string }) => {\n const { scaffoldPlugin } = await import(\"@gpc-cli/core\");\n const pluginName = name.startsWith(\"gpc-plugin-\") ? name : `gpc-plugin-${name}`;\n const dir = opts.dir ?? `./${pluginName}`;\n\n const result = await scaffoldPlugin({ name, dir, description: opts.description });\n\n console.log(`Plugin scaffolded at ${result.dir}/\\n`);\n console.log(\"Files created:\");\n for (const f of result.files) {\n console.log(` ${f}`);\n }\n console.log(`\\nNext steps:`);\n console.log(` cd ${pluginName}`);\n console.log(` npm install`);\n console.log(` npm run build`);\n console.log(` npm test`);\n });\n\n cmd\n .command(\"approve <name>\")\n .description(\"Approve a third-party plugin for loading\")\n .action(async (name: string) => {\n const { approvePlugin } = await import(\"@gpc-cli/config\");\n await approvePlugin(name);\n console.log(`Plugin \"${name}\" approved. It will be loaded on next run.`);\n });\n\n cmd\n .command(\"revoke <name>\")\n .description(\"Revoke approval for a third-party plugin\")\n .action(async (name: string) => {\n const { revokePluginApproval } = await import(\"@gpc-cli/config\");\n const removed = await revokePluginApproval(name);\n if (removed) {\n console.log(`Plugin \"${name}\" approval revoked.`);\n } else {\n console.log(`Plugin \"${name}\" was not in the approved list.`);\n }\n });\n\n const REGISTRY_URL =\n \"https://raw.githubusercontent.com/yasserstudio/gpc-plugins/main/registry.json\";\n\n interface RegistryPlugin {\n name: string;\n description: string;\n version: string;\n author?: string;\n tags?: string[];\n }\n\n cmd\n .command(\"search [query]\")\n .description(\"Search the GPC plugin registry\")\n .action(async (query?: string) => {\n try {\n const res = await fetch(REGISTRY_URL);\n if (!res.ok) throw new Error(`Registry fetch failed: ${res.status}`);\n const plugins = (await res.json()) as RegistryPlugin[];\n const filtered = query\n ? plugins.filter(\n (p) =>\n p.name.includes(query) ||\n p.description?.toLowerCase().includes(query.toLowerCase()),\n )\n : plugins;\n\n if (filtered.length === 0) {\n console.log(`No plugins found${query ? ` matching \"${query}\"` : \"\"}.`);\n return;\n }\n\n for (const p of filtered) {\n console.log(` ${p.name}@${p.version}`);\n if (p.description) console.log(` ${p.description}`);\n }\n console.log(`\\nInstall: gpc plugins install <name>`);\n } catch (error) {\n console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);\n process.exit(4);\n }\n });\n\n cmd\n .command(\"install <name>\")\n .description(\"Install a plugin from npm\")\n .action(async (name: string) => {\n const { spawnSync } = await import(\"node:child_process\");\n console.log(`Installing plugin \"${name}\"...`);\n try {\n // Use spawnSync with an array to avoid shell injection — no shell is invoked\n const result = spawnSync(\"npm\", [\"install\", \"-g\", name], { stdio: \"inherit\" });\n if (result.status !== 0) {\n throw new Error(`npm install exited with code ${result.status ?? \"unknown\"}`);\n }\n const { approvePlugin } = await import(\"@gpc-cli/config\");\n await approvePlugin(name);\n console.log(`\\nPlugin \"${name}\" installed and approved. It will be loaded on next run.`);\n console.log(`Configure it in .gpcrc.json: { \"plugins\": [\"${name}\"] }`);\n } catch (error) {\n console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);\n process.exit(4);\n }\n });\n\n cmd\n .command(\"uninstall <name>\")\n .description(\"Uninstall a plugin and revoke its approval\")\n .action(async (name: string) => {\n const { spawnSync } = await import(\"node:child_process\");\n console.log(`Uninstalling plugin \"${name}\"...`);\n try {\n // Use spawnSync with an array to avoid shell injection — no shell is invoked\n const result = spawnSync(\"npm\", [\"uninstall\", \"-g\", name], { stdio: \"inherit\" });\n if (result.status !== 0) {\n throw new Error(`npm uninstall exited with code ${result.status ?? \"unknown\"}`);\n }\n const { revokePluginApproval } = await import(\"@gpc-cli/config\");\n await revokePluginApproval(name);\n console.log(`\\nPlugin \"${name}\" uninstalled and approval revoked.`);\n } catch (error) {\n console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);\n process.exit(4);\n }\n });\n}\n\n/**\n * Wrap all registered commands so plugin hooks fire before/after each command.\n */\nfunction wrapCommandHooks(program: Command, manager: PluginManager): void {\n program.hook(\"preAction\", async (thisCommand) => {\n const event: CommandEvent = {\n command: getFullCommandName(thisCommand),\n args: thisCommand.opts(),\n app: program.opts()[\"app\"] as string | undefined,\n startedAt: new Date(),\n };\n\n // Store on the command for afterCommand/onError\n (thisCommand as unknown as Record<string, unknown>)[\"__pluginEvent\"] = event;\n\n await manager.runBeforeCommand(event);\n });\n\n program.hook(\"postAction\", async (thisCommand) => {\n const event: CommandEvent = (thisCommand as unknown as Record<string, unknown>)[\n \"__pluginEvent\"\n ] as CommandEvent;\n if (!event) return;\n\n const result: CommandResult = {\n success: true,\n durationMs: Date.now() - event.startedAt.getTime(),\n exitCode: 0,\n };\n\n await manager.runAfterCommand(event, result);\n });\n}\n\nfunction getFullCommandName(cmd: Command): string {\n const parts: string[] = [];\n let current: Command | null = cmd;\n while (current && current.name() !== \"gpc\") {\n parts.unshift(current.name());\n current = current.parent;\n }\n return parts.join(\" \");\n}\n","/**\n * Shared error formatting for CLI output.\n * Extracts error code, message, and suggestion from typed errors (GpcError, AuthError, ApiError, ConfigError).\n */\n\ninterface TypedError {\n message: string;\n code?: string;\n suggestion?: string;\n exitCode?: number;\n /** When true, error handler prints nothing (e.g., user-aborted operations). */\n silent?: boolean;\n}\n\nfunction isTypedError(error: unknown): error is Error & TypedError {\n return (\n error instanceof Error && \"code\" in error && typeof (error as TypedError).code === \"string\"\n );\n}\n\nconst AUTH_KEYWORDS = [\"AUTH\", \"UNAUTHENTICATED\", \"PERMISSION_DENIED\", \"401\", \"403\"];\n\nfunction isAuthRelatedError(error: unknown): boolean {\n if (isTypedError(error)) {\n // Update errors hit GitHub, not Google Play — never an auth issue\n if (error.code?.startsWith(\"UPDATE_\")) return false;\n if (error.exitCode === 3) return true;\n if (error.code && AUTH_KEYWORDS.some((k) => error.code?.includes(k))) return true;\n }\n const msg = error instanceof Error ? error.message : String(error);\n return AUTH_KEYWORDS.some((k) => msg.includes(k));\n}\n\n/**\n * Format an error for CLI output. Prints:\n * Error [CODE]: message\n * Suggestion: suggestion (if available)\n *\n * Returns the appropriate exit code.\n */\nexport function handleCliError(error: unknown): number {\n // Silent errors (e.g., user abort) — don't print anything\n if (isTypedError(error) && error.silent) {\n return error.exitCode ?? 0;\n }\n\n const authHint = isAuthRelatedError(error)\n ? \"\\n\\u2192 Run gpc doctor to diagnose your credentials.\"\n : \"\";\n\n if (isTypedError(error)) {\n console.error(`Error [${error.code}]: ${error.message}`);\n if (error.suggestion) {\n console.error(`Suggestion: ${error.suggestion}`);\n }\n if (authHint) console.error(authHint);\n return error.exitCode ?? 1;\n }\n\n const message = error instanceof Error ? error.message : String(error);\n console.error(`Error: ${message}`);\n if (authHint) console.error(authHint);\n return 1;\n}\n"],"mappings":"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","names":["_","loader"]}
@@ -78,7 +78,7 @@ Configuration file created: ${path}`);
78
78
  });
79
79
  console.log("\nVerifying setup...");
80
80
  try {
81
- const { registerDoctorCommand } = await import("./doctor-QCCWG6Y3.js");
81
+ const { registerDoctorCommand } = await import("./doctor-Q4WI432G.js");
82
82
  const { Command } = await import("commander");
83
83
  const doctorProgram = new Command();
84
84
  doctorProgram.option("-o, --output <format>", "Output format").option("-j, --json", "JSON mode");
@@ -107,4 +107,4 @@ Configuration file created: ${path}`);
107
107
  export {
108
108
  registerConfigCommands
109
109
  };
110
- //# sourceMappingURL=config-NY3TZGVS.js.map
110
+ //# sourceMappingURL=config-JOYJ7TQC.js.map
@@ -114,7 +114,8 @@ function checkConfigKeys(config) {
114
114
  name: "config-keys",
115
115
  status: "warn",
116
116
  message: `Unknown config key${unknown.length > 1 ? "s" : ""}: ${unknown.join(", ")}`,
117
- suggestion: `Valid keys: ${[...KNOWN_CONFIG_KEYS].sort().join(", ")}`
117
+ suggestion: `Valid keys: ${[...KNOWN_CONFIG_KEYS].sort().join(", ")}`,
118
+ fixData: { keys: unknown.join(", ") }
118
119
  };
119
120
  }
120
121
  function checkCiEnvironment() {
@@ -140,7 +141,7 @@ function checkCiEnvironment() {
140
141
  };
141
142
  }
142
143
  async function checkGpcVersion() {
143
- const currentVersion = "0.9.47";
144
+ const currentVersion = "0.9.49";
144
145
  if (currentVersion === "0.0.0") {
145
146
  return { name: "version", status: "info", message: "GPC development build" };
146
147
  }
@@ -316,6 +317,23 @@ async function checkAppAccess(packageName, accessToken) {
316
317
  };
317
318
  }
318
319
  }
320
+ var VERIFICATION_ENFORCEMENT = /* @__PURE__ */ new Date("2026-09-01");
321
+ function checkVerificationDeadline() {
322
+ if (Date.now() < VERIFICATION_ENFORCEMENT.getTime()) {
323
+ return {
324
+ name: "verification",
325
+ status: "warn",
326
+ message: "Android developer verification enforcement begins September 2026 (BR, ID, SG, TH)",
327
+ suggestion: "Run 'gpc verify' for details and resources"
328
+ };
329
+ }
330
+ return {
331
+ name: "verification",
332
+ status: "info",
333
+ message: "Android developer verification is being enforced. Ensure your account is verified.",
334
+ suggestion: "Run 'gpc verify' to check your status"
335
+ };
336
+ }
319
337
  async function applyFix(check) {
320
338
  switch (check.name) {
321
339
  case "config-dir":
@@ -348,6 +366,21 @@ async function applyFix(check) {
348
366
  await initConfig({});
349
367
  return "Initialized config file";
350
368
  }
369
+ case "version": {
370
+ return "Run: gpc update";
371
+ }
372
+ case "auth": {
373
+ return "Run: gpc auth login --service-account <path/to/key.json>";
374
+ }
375
+ case "config-keys": {
376
+ const keys = check.fixData?.keys;
377
+ if (!keys) return null;
378
+ const { deleteConfigValue } = await import("@gpc-cli/config");
379
+ for (const key of keys.split(",")) {
380
+ await deleteConfigValue(key.trim());
381
+ }
382
+ return `Removed unknown keys: ${keys}`;
383
+ }
351
384
  default:
352
385
  return null;
353
386
  }
@@ -640,6 +673,7 @@ function registerDoctorCommand(program) {
640
673
  });
641
674
  }
642
675
  }
676
+ results.push(checkVerificationDeadline());
643
677
  if (opts["fix"]) {
644
678
  for (const r of results) {
645
679
  if (r.status === "fail" || r.status === "warn") {
@@ -703,6 +737,7 @@ export {
703
737
  checkNodeVersion,
704
738
  checkPackageName,
705
739
  checkProxy,
740
+ checkVerificationDeadline,
706
741
  registerDoctorCommand
707
742
  };
708
- //# sourceMappingURL=doctor-QCCWG6Y3.js.map
743
+ //# sourceMappingURL=doctor-Q4WI432G.js.map