@gpc-cli/core 0.9.53 → 0.9.54

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -60,6 +60,7 @@ const analysis = await analyzeBundle("./app.aab");
60
60
  | **Testers** | `listTesters`, `addTesters`, `removeTesters`, `importTestersFromCsv` |
61
61
  | **Bundle** | `analyzeBundle`, `compareBundles` (zero-dependency AAB/APK size analysis) |
62
62
  | **Publishing** | `publish` (end-to-end: upload + track + notes + commit) |
63
+ | **Changelog** | `generateChangelog`, `fetchChangelog`, `formatChangelogEntry`, `buildLocaleBundle`, `renderPlayStore`, `renderMarkdown`, `renderJson`, `renderPrompt`, `translateBundle`, `resolveLocales` |
63
64
  | **Validation** | `validateUploadFile`, `validateImage`, `validatePreSubmission` |
64
65
 
65
66
  ## Utilities
package/dist/index.d.ts CHANGED
@@ -109,6 +109,7 @@ interface AppInfo {
109
109
  }
110
110
  declare function getAppInfo(client: PlayApiClient, packageName: string): Promise<AppInfo>;
111
111
 
112
+ declare function waitForBundleProcessing(client: PlayApiClient, packageName: string, editId: string, versionCode: number, backoff?: number[]): Promise<void>;
112
113
  interface UploadResult {
113
114
  versionCode: number;
114
115
  track: string;
@@ -183,6 +184,19 @@ declare function fetchReleaseNotes(client: PlayApiClient, packageName: string, t
183
184
  language: string;
184
185
  text: string;
185
186
  }[]>;
187
+ interface ApplyReleaseNotesResult {
188
+ track: string;
189
+ versionCodes: string[];
190
+ localeCount: number;
191
+ releaseNotes: {
192
+ language: string;
193
+ text: string;
194
+ }[];
195
+ }
196
+ declare function applyReleaseNotes(client: PlayApiClient, packageName: string, track: string, releaseNotes: {
197
+ language: string;
198
+ text: string;
199
+ }[], commitOptions?: EditCommitOptions): Promise<ApplyReleaseNotesResult>;
186
200
  interface ReleaseDiff {
187
201
  field: string;
188
202
  track1Value: string;
@@ -1398,6 +1412,11 @@ interface TranslatedBundle extends LocaleBundle {
1398
1412
  failures: TranslationFailure[];
1399
1413
  }
1400
1414
  declare function translateBundle(bundle: LocaleBundle, options: TranslateBundleOptions): Promise<TranslatedBundle>;
1415
+ declare function validateBundleForApply(bundle: LocaleBundle): string[];
1416
+ declare function bundleToReleaseNotes(bundle: LocaleBundle): {
1417
+ language: string;
1418
+ text: string;
1419
+ }[];
1401
1420
 
1402
1421
  type Renderer = (g: GeneratedChangelog) => string;
1403
1422
  declare const RENDERERS: Record<OutputMode, Renderer>;
@@ -1453,4 +1472,4 @@ declare function decodeNotification(base64Payload: string): DecodedNotification;
1453
1472
  */
1454
1473
  declare function formatNotification(notification: DecodedNotification): Record<string, unknown>;
1455
1474
 
1456
- export { ApiError, type AppInfo, type AppStatus, type AuditEntry, type BatchSyncResult, type BundleAnalysis, type BundleComparison, type BundleEntry, type BundleSizeCheckResult, type BundleSizeConfig, type ChangelogEntry, type CommandContext, type CommitCluster, ConfigError, type CreateEnterpriseAppParams, DEFAULT_LIMITS, DEFAULT_MODELS, DEFAULT_PREFLIGHT_CONFIG, type DecodedNotification, type DiffToken, type DiscoverPluginsOptions, type DryRunPublishResult, type DryRunResult, type DryRunUploadResult, type ErrorReason, type ExportImagesOptions, type ExportImagesSummary, type FastlaneDetection, type FastlaneLane, type FetchChangelogOptions, type FieldLintResult, type FileValidationResult, type FindingSeverity, GOOGLE_PLAY_LANGUAGES, type GenerateOptions, type GeneratedChangelog, type GetAppStatusOptions, type GitNotesOptions, type GitReleaseNotes, type GitRunner, GpcError, type ImageValidationResult, type InitOptions, type InitResult, type InternalSharingUploadResult, type ListIapOptions, type ListSubscriptionsOptions, type ListUsersOptions, type ListVoidedOptions, type ListingDiff, type ListingFieldLimits, type ListingLintResult, type ListingsResult, type LoadedPlugin, type LocaleBundle, type LocaleEntry, type MigrationResult, NetworkError, type OneTimeProductDiff, type OutputMode, PERMISSION_PROPAGATION_WARNING, PLACEHOLDER_TEXT, PLAY_STORE_LIMIT, PROVIDER_WHITELIST, type ParsedCommit, type ParsedManifest, type ParsedMonth, type PlayStoreFormat, type PlayStoreRenderOptions, PluginManager, type PreflightConfig, type PreflightFinding, type PreflightOptions, type PreflightResult, type PreflightScanner, type Provider, type PublishOptions, type PublishResult, type PushResult, type QuotaUsage, RENDERERS, type RawCommit, type ReleaseDiff, type ReleaseNotesValidation, type ReleaseStatusResult, type Renderer, type ResolveAiConfigOptions, type ResolveLocalesOptions, type ReviewAnalysis, type ReviewExportOptions, type ReviewsFilterOptions, type RtdnStatus, SECTION_ORDER, SENSITIVE_ARG_KEYS, SENSITIVE_KEYS, SEVERITY_ORDER, type ScaffoldOptions, type ScaffoldResult, type Spinner, type StatusDiff, type StatusRelease, type StatusReviews, type StatusVitalMetric, type SubscriptionAnalytics, type SubscriptionDiff, type SyncResult, type ThresholdResult, type TrainConfig, type TrainState, type TranslateBundleOptions, type TranslatedBundle, type TranslationFailure, type TranslationPath, type TranslationResult, type Translator, type TranslatorConfig, type UploadResult, type ValidateCheck, type ValidateOptions, type ValidateResult, type VersionVitalsComparison, type VersionVitalsRow, type VitalsOverview, type VitalsQueryOptions, type VitalsTrendComparison, type WatchOptions, type WatchVitalsOptions, type WebhookPayload, abortTrain, acknowledgeProductPurchase, activateBasePlan, activateOffer, addRecoveryTargeting, addTesters, advanceTrain, analyzeBundle, analyzeRemoteListings, analyzeReviews, batchGetOrders, batchSyncInAppProducts, buildLocaleBundle, cancelRecoveryAction, cancelSubscriptionPurchase, cancelSubscriptionV2, checkBundleSize, checkThreshold, classifyError, clearAuditLog, compareBundles, compareVersionVitals, compareVitalsTrend, computeStatusDiff, consumeProductPurchase, convertRegionPrices, createAuditEntry, createDeviceTier, createEnterpriseApp, createExternalTransaction, createGrant, createInAppProduct, createOffer, createOneTimeOffer, createOneTimeProduct, createRecoveryAction, createSpinner, createSubscription, createTrack, createTranslator, deactivateBasePlan, deactivateOffer, decodeNotification, defaultGitRunner, deferSubscriptionPurchase, deferSubscriptionV2, deleteBasePlan, deleteGrant, deleteImage, deleteInAppProduct, deleteListing, deleteOffer, deleteOneTimeOffer, deleteOneTimeProduct, deleteSubscription, deployRecoveryAction, detectFastlane, detectOutputFormat, diffListings, diffListingsCommand, diffListingsEnhanced, diffOneTimeProduct, diffReleases, diffSubscription, discoverPlugins, downloadGeneratedApk, downloadReport, exportImages, exportReviews, fetchAggregateCost, fetchChangelog, fetchReleaseNotes, formatChangelogEntry, formatCustomPayload, formatDiscordPayload, formatJunit, formatNotification, formatOutput, formatPathLabel, formatSlackPayload, formatStatusDiff, formatStatusSummary, formatStatusTable, formatWordDiff, generateChangelog, generateMigrationPlan, generateNotesFromGit, getAllScannerNames, getAppInfo, getAppStatus, getCountryAvailability, getDeviceTier, getExternalTransaction, getInAppProduct, getListings, getOffer, getOneTimeOffer, getOneTimeProduct, getOrderDetails, getProductPurchase, getProductPurchaseV2, getQuotaUsage, getReleasesStatus, getReview, getRtdnStatus, getSubscription, getSubscriptionAnalytics, getSubscriptionPurchase, getTrainStatus, getUser, getVitalsAnomalies, getVitalsAnr, getVitalsBattery, getVitalsCrashes, getVitalsErrorCount, getVitalsLmk, getVitalsMemory, getVitalsOverview, getVitalsRendering, getVitalsStartup, importDataSafety, importTestersFromCsv, initAudit, initProject, inviteUser, isFinancialReportType, isStatsReportType, isValidBcp47, isValidReportType, isValidStatsDimension, lintListing, lintListings, lintLocalListings, listAchievements, listAuditEvents, listDeviceTiers, listEvents, listGeneratedApks, listGrants, listImages, listInAppProducts, listLeaderboards, listOffers, listOneTimeOffers, listOneTimeProducts, listRecoveryActions, listReports, listReviews, listSubscriptions, listTesters, listTracks, listUsers, listVoidedPurchases, loadPreflightConfig, loadStatusCache, maybePaginate, migratePrices, parseAppfile, parseCommit, parseFastfile, parseGrantArg, parseMonth, parseRemoteUrl, pauseTrain, promoteRelease, publish, publishEnterpriseApp, pullListings, pushListings, readListingsFromDir, readReleaseNotesFromDir, redactAuditArgs, redactSensitive, refundExternalTransaction, refundOrder, relativeTime, removeTesters, removeUser, renderJson, renderMarkdown, renderPlayStore, renderPlayStoreJson, renderPlayStoreMd, renderPlayStorePrompt, renderPrompt, replyToReview, resolveAiConfig, resolveLocales, revokeSubscriptionPurchase, runPreflight, runWatchLoop, safePath, safePathWithin, saveStatusCache, scaffoldPlugin, searchAuditEvents, searchVitalsErrors, sendNotification, sendWebhook, sortResults, startTrain, statusHasBreach, syncInAppProducts, topFiles, trackBreachState, translateBundle, updateAppDetails, updateDataSafety, updateGrant, updateInAppProduct, updateListing, updateOffer, updateOneTimeOffer, updateOneTimeProduct, updateRollout, updateSubscription, updateTrackConfig, updateUser, uploadExternallyHosted, uploadImage, uploadInternalSharing, uploadRelease, validateImage, validateLanguageCode, validatePackageName, validatePreSubmission, validateReleaseNotes, validateSku, validateTrackName, validateUploadFile, validateVersionCode, watchVitalsWithAutoHalt, wordDiff, writeAuditLog, writeListingsToDir, writeMigrationOutput };
1475
+ export { ApiError, type AppInfo, type AppStatus, type ApplyReleaseNotesResult, type AuditEntry, type BatchSyncResult, type BundleAnalysis, type BundleComparison, type BundleEntry, type BundleSizeCheckResult, type BundleSizeConfig, type ChangelogEntry, type CommandContext, type CommitCluster, ConfigError, type CreateEnterpriseAppParams, DEFAULT_LIMITS, DEFAULT_MODELS, DEFAULT_PREFLIGHT_CONFIG, type DecodedNotification, type DiffToken, type DiscoverPluginsOptions, type DryRunPublishResult, type DryRunResult, type DryRunUploadResult, type ErrorReason, type ExportImagesOptions, type ExportImagesSummary, type FastlaneDetection, type FastlaneLane, type FetchChangelogOptions, type FieldLintResult, type FileValidationResult, type FindingSeverity, GOOGLE_PLAY_LANGUAGES, type GenerateOptions, type GeneratedChangelog, type GetAppStatusOptions, type GitNotesOptions, type GitReleaseNotes, type GitRunner, GpcError, type ImageValidationResult, type InitOptions, type InitResult, type InternalSharingUploadResult, type ListIapOptions, type ListSubscriptionsOptions, type ListUsersOptions, type ListVoidedOptions, type ListingDiff, type ListingFieldLimits, type ListingLintResult, type ListingsResult, type LoadedPlugin, type LocaleBundle, type LocaleEntry, type MigrationResult, NetworkError, type OneTimeProductDiff, type OutputMode, PERMISSION_PROPAGATION_WARNING, PLACEHOLDER_TEXT, PLAY_STORE_LIMIT, PROVIDER_WHITELIST, type ParsedCommit, type ParsedManifest, type ParsedMonth, type PlayStoreFormat, type PlayStoreRenderOptions, PluginManager, type PreflightConfig, type PreflightFinding, type PreflightOptions, type PreflightResult, type PreflightScanner, type Provider, type PublishOptions, type PublishResult, type PushResult, type QuotaUsage, RENDERERS, type RawCommit, type ReleaseDiff, type ReleaseNotesValidation, type ReleaseStatusResult, type Renderer, type ResolveAiConfigOptions, type ResolveLocalesOptions, type ReviewAnalysis, type ReviewExportOptions, type ReviewsFilterOptions, type RtdnStatus, SECTION_ORDER, SENSITIVE_ARG_KEYS, SENSITIVE_KEYS, SEVERITY_ORDER, type ScaffoldOptions, type ScaffoldResult, type Spinner, type StatusDiff, type StatusRelease, type StatusReviews, type StatusVitalMetric, type SubscriptionAnalytics, type SubscriptionDiff, type SyncResult, type ThresholdResult, type TrainConfig, type TrainState, type TranslateBundleOptions, type TranslatedBundle, type TranslationFailure, type TranslationPath, type TranslationResult, type Translator, type TranslatorConfig, type UploadResult, type ValidateCheck, type ValidateOptions, type ValidateResult, type VersionVitalsComparison, type VersionVitalsRow, type VitalsOverview, type VitalsQueryOptions, type VitalsTrendComparison, type WatchOptions, type WatchVitalsOptions, type WebhookPayload, abortTrain, acknowledgeProductPurchase, activateBasePlan, activateOffer, addRecoveryTargeting, addTesters, advanceTrain, analyzeBundle, analyzeRemoteListings, analyzeReviews, applyReleaseNotes, batchGetOrders, batchSyncInAppProducts, buildLocaleBundle, bundleToReleaseNotes, cancelRecoveryAction, cancelSubscriptionPurchase, cancelSubscriptionV2, checkBundleSize, checkThreshold, classifyError, clearAuditLog, compareBundles, compareVersionVitals, compareVitalsTrend, computeStatusDiff, consumeProductPurchase, convertRegionPrices, createAuditEntry, createDeviceTier, createEnterpriseApp, createExternalTransaction, createGrant, createInAppProduct, createOffer, createOneTimeOffer, createOneTimeProduct, createRecoveryAction, createSpinner, createSubscription, createTrack, createTranslator, deactivateBasePlan, deactivateOffer, decodeNotification, defaultGitRunner, deferSubscriptionPurchase, deferSubscriptionV2, deleteBasePlan, deleteGrant, deleteImage, deleteInAppProduct, deleteListing, deleteOffer, deleteOneTimeOffer, deleteOneTimeProduct, deleteSubscription, deployRecoveryAction, detectFastlane, detectOutputFormat, diffListings, diffListingsCommand, diffListingsEnhanced, diffOneTimeProduct, diffReleases, diffSubscription, discoverPlugins, downloadGeneratedApk, downloadReport, exportImages, exportReviews, fetchAggregateCost, fetchChangelog, fetchReleaseNotes, formatChangelogEntry, formatCustomPayload, formatDiscordPayload, formatJunit, formatNotification, formatOutput, formatPathLabel, formatSlackPayload, formatStatusDiff, formatStatusSummary, formatStatusTable, formatWordDiff, generateChangelog, generateMigrationPlan, generateNotesFromGit, getAllScannerNames, getAppInfo, getAppStatus, getCountryAvailability, getDeviceTier, getExternalTransaction, getInAppProduct, getListings, getOffer, getOneTimeOffer, getOneTimeProduct, getOrderDetails, getProductPurchase, getProductPurchaseV2, getQuotaUsage, getReleasesStatus, getReview, getRtdnStatus, getSubscription, getSubscriptionAnalytics, getSubscriptionPurchase, getTrainStatus, getUser, getVitalsAnomalies, getVitalsAnr, getVitalsBattery, getVitalsCrashes, getVitalsErrorCount, getVitalsLmk, getVitalsMemory, getVitalsOverview, getVitalsRendering, getVitalsStartup, importDataSafety, importTestersFromCsv, initAudit, initProject, inviteUser, isFinancialReportType, isStatsReportType, isValidBcp47, isValidReportType, isValidStatsDimension, lintListing, lintListings, lintLocalListings, listAchievements, listAuditEvents, listDeviceTiers, listEvents, listGeneratedApks, listGrants, listImages, listInAppProducts, listLeaderboards, listOffers, listOneTimeOffers, listOneTimeProducts, listRecoveryActions, listReports, listReviews, listSubscriptions, listTesters, listTracks, listUsers, listVoidedPurchases, loadPreflightConfig, loadStatusCache, maybePaginate, migratePrices, parseAppfile, parseCommit, parseFastfile, parseGrantArg, parseMonth, parseRemoteUrl, pauseTrain, promoteRelease, publish, publishEnterpriseApp, pullListings, pushListings, readListingsFromDir, readReleaseNotesFromDir, redactAuditArgs, redactSensitive, refundExternalTransaction, refundOrder, relativeTime, removeTesters, removeUser, renderJson, renderMarkdown, renderPlayStore, renderPlayStoreJson, renderPlayStoreMd, renderPlayStorePrompt, renderPrompt, replyToReview, resolveAiConfig, resolveLocales, revokeSubscriptionPurchase, runPreflight, runWatchLoop, safePath, safePathWithin, saveStatusCache, scaffoldPlugin, searchAuditEvents, searchVitalsErrors, sendNotification, sendWebhook, sortResults, startTrain, statusHasBreach, syncInAppProducts, topFiles, trackBreachState, translateBundle, updateAppDetails, updateDataSafety, updateGrant, updateInAppProduct, updateListing, updateOffer, updateOneTimeOffer, updateOneTimeProduct, updateRollout, updateSubscription, updateTrackConfig, updateUser, uploadExternallyHosted, uploadImage, uploadInternalSharing, uploadRelease, validateBundleForApply, validateImage, validateLanguageCode, validatePackageName, validatePreSubmission, validateReleaseNotes, validateSku, validateTrackName, validateUploadFile, validateVersionCode, waitForBundleProcessing, watchVitalsWithAutoHalt, wordDiff, writeAuditLog, writeListingsToDir, writeMigrationOutput };
package/dist/index.js CHANGED
@@ -650,6 +650,20 @@ function formatSize(bytes) {
650
650
  }
651
651
 
652
652
  // src/commands/releases.ts
653
+ var BUNDLE_POLL_BACKOFF = [2e3, 3e3, 5e3, 8e3, 13e3];
654
+ async function waitForBundleProcessing(client, packageName, editId, versionCode, backoff = BUNDLE_POLL_BACKOFF) {
655
+ for (let i = 0; i < backoff.length; i++) {
656
+ const bundles = await client.bundles.list(packageName, editId);
657
+ if (bundles.some((b) => b.versionCode === versionCode)) return;
658
+ await new Promise((r) => setTimeout(r, backoff[i]));
659
+ }
660
+ throw new GpcError(
661
+ `Bundle versionCode ${versionCode} not ready after ${backoff.length} poll attempts (~${Math.round(backoff.reduce((a, b) => a + b, 0) / 1e3)}s)`,
662
+ "BUNDLE_PROCESSING_TIMEOUT",
663
+ 4,
664
+ "The AAB is still being processed by Google. Retry the upload, or use --status draft and commit later."
665
+ );
666
+ }
653
667
  async function withRetryOnConflict(client, packageName, operation) {
654
668
  const edit = await client.edits.insert(packageName);
655
669
  try {
@@ -763,6 +777,9 @@ ${validation.errors.join("\n")}`,
763
777
  uploadOpts,
764
778
  options.deviceTierConfigId
765
779
  );
780
+ if (!isApk) {
781
+ await waitForBundleProcessing(client, packageName, edit.id, bundle.versionCode);
782
+ }
766
783
  if (options.mappingFile) {
767
784
  await client.deobfuscation.upload(
768
785
  packageName,
@@ -1023,6 +1040,35 @@ async function fetchReleaseNotes(client, packageName, track) {
1023
1040
  });
1024
1041
  }
1025
1042
  }
1043
+ async function applyReleaseNotes(client, packageName, track, releaseNotes, commitOptions) {
1044
+ return withRetryOnConflict(client, packageName, async (edit) => {
1045
+ const trackData = await client.tracks.get(packageName, edit.id, track);
1046
+ const draft = trackData.releases?.find((r) => r.status === "draft");
1047
+ if (!draft) {
1048
+ throw new GpcError(
1049
+ `No draft release found on track "${track}"`,
1050
+ "RELEASE_NO_DRAFT",
1051
+ 1,
1052
+ `Upload an AAB/APK first to create a draft, or check the --track value. Current track: "${track}".`
1053
+ );
1054
+ }
1055
+ const patched = {
1056
+ ...draft,
1057
+ releaseNotes
1058
+ };
1059
+ await client.tracks.update(packageName, edit.id, track, patched);
1060
+ if (!commitOptions?.changesNotSentForReview) {
1061
+ await client.edits.validate(packageName, edit.id);
1062
+ }
1063
+ await client.edits.commit(packageName, edit.id, commitOptions);
1064
+ return {
1065
+ track,
1066
+ versionCodes: draft.versionCodes || [],
1067
+ localeCount: releaseNotes.length,
1068
+ releaseNotes
1069
+ };
1070
+ });
1071
+ }
1026
1072
  async function diffReleases(client, packageName, fromTrack, toTrack) {
1027
1073
  const edit = await client.edits.insert(packageName);
1028
1074
  try {
@@ -7377,7 +7423,16 @@ var KNOWN_TYPES = /* @__PURE__ */ new Set([
7377
7423
  "release"
7378
7424
  ]);
7379
7425
  var FILTERED_TYPES = /* @__PURE__ */ new Set(["chore", "refactor", "test", "build", "style", "merge"]);
7380
- var SECTION_ORDER = ["breaking", "feat", "fix", "perf", "docs", "ci", "release", "other"];
7426
+ var SECTION_ORDER = [
7427
+ "breaking",
7428
+ "feat",
7429
+ "fix",
7430
+ "perf",
7431
+ "docs",
7432
+ "ci",
7433
+ "release",
7434
+ "other"
7435
+ ];
7381
7436
  var FIXUP_PATTERNS = [
7382
7437
  /^wip\b/i,
7383
7438
  /^fix\s+typo\b/i,
@@ -7841,14 +7896,18 @@ function renderPrompt(g) {
7841
7896
  if (g.headlineCandidates.length > 0) {
7842
7897
  lines.push("HEADLINE CANDIDATES (largest first):");
7843
7898
  for (const c of g.headlineCandidates) {
7844
- lines.push(` ${c.label} (weight ${c.weight}, ${c.commits.length} commits, primary ${c.primaryType})`);
7899
+ lines.push(
7900
+ ` ${c.label} (weight ${c.weight}, ${c.commits.length} commits, primary ${c.primaryType})`
7901
+ );
7845
7902
  }
7846
7903
  lines.push("");
7847
7904
  }
7848
7905
  lines.push("CLUSTERED COMMITS:");
7849
7906
  lines.push("");
7850
7907
  for (const cluster of g.clusters) {
7851
- lines.push(`[cluster: ${cluster.label}, weight ${cluster.weight}, ${cluster.commits.length} commits, primary ${cluster.primaryType}]`);
7908
+ lines.push(
7909
+ `[cluster: ${cluster.label}, weight ${cluster.weight}, ${cluster.commits.length} commits, primary ${cluster.primaryType}]`
7910
+ );
7852
7911
  for (const commit of cluster.commits) {
7853
7912
  lines.push(`- ${commit.type}: ${safeLine(commit.subject)} (${commit.sha.slice(0, 7)})`);
7854
7913
  if (commit.files.length > 0) {
@@ -8159,7 +8218,9 @@ function renderPlayStorePrompt(bundle, g) {
8159
8218
  const source = bundle.locales.find((e) => e.language === bundle.sourceLanguage);
8160
8219
  const targets = bundle.locales.filter((e) => e.language !== bundle.sourceLanguage);
8161
8220
  const lines = [];
8162
- lines.push(`You are translating Play Store "What's new" release notes from ${bundle.sourceLanguage}.`);
8221
+ lines.push(
8222
+ `You are translating Play Store "What's new" release notes from ${bundle.sourceLanguage}.`
8223
+ );
8163
8224
  lines.push("");
8164
8225
  lines.push("TARGETS:");
8165
8226
  for (const t of targets) lines.push(` - ${t.language}`);
@@ -8170,7 +8231,9 @@ function renderPlayStorePrompt(bundle, g) {
8170
8231
  lines.push('- Preserve the bullet format (one item per line, starts with "- ")');
8171
8232
  lines.push("- Keep a user-facing tone (no internal jargon)");
8172
8233
  lines.push('- Do not translate technical names (package names, CLI flags, "GPC")');
8173
- lines.push("- Drop the conventional-commit prefix (feat:/fix:) if it feels unnatural in the target language");
8234
+ lines.push(
8235
+ "- Drop the conventional-commit prefix (feat:/fix:) if it feels unnatural in the target language"
8236
+ );
8174
8237
  lines.push("");
8175
8238
  lines.push(`SOURCE (${bundle.sourceLanguage}, ${source?.chars ?? 0}/${bundle.limit} chars):`);
8176
8239
  lines.push("```");
@@ -8290,6 +8353,21 @@ async function translateBundle(bundle, options) {
8290
8353
  }
8291
8354
  return translated;
8292
8355
  }
8356
+ function validateBundleForApply(bundle) {
8357
+ const errors = [];
8358
+ for (const entry of bundle.locales) {
8359
+ if (entry.status === "placeholder") {
8360
+ errors.push(`${entry.language}: untranslated placeholder \u2014 use --ai or remove this locale`);
8361
+ }
8362
+ if (entry.status === "failed") {
8363
+ errors.push(`${entry.language}: translation failed \u2014 retry or remove this locale`);
8364
+ }
8365
+ }
8366
+ return errors;
8367
+ }
8368
+ function bundleToReleaseNotes(bundle) {
8369
+ return bundle.locales.filter((e) => e.status !== "placeholder" && e.status !== "failed").map((e) => ({ language: e.language, text: e.text }));
8370
+ }
8293
8371
 
8294
8372
  // src/commands/changelog-renderers/index.ts
8295
8373
  var RENDERERS = {
@@ -8481,9 +8559,11 @@ export {
8481
8559
  analyzeBundle,
8482
8560
  analyzeRemoteListings,
8483
8561
  analyzeReviews2 as analyzeReviews,
8562
+ applyReleaseNotes,
8484
8563
  batchGetOrders,
8485
8564
  batchSyncInAppProducts,
8486
8565
  buildLocaleBundle,
8566
+ bundleToReleaseNotes,
8487
8567
  cancelRecoveryAction,
8488
8568
  cancelSubscriptionPurchase,
8489
8569
  cancelSubscriptionV2,
@@ -8693,6 +8773,7 @@ export {
8693
8773
  uploadImage,
8694
8774
  uploadInternalSharing,
8695
8775
  uploadRelease,
8776
+ validateBundleForApply,
8696
8777
  validateImage,
8697
8778
  validateLanguageCode,
8698
8779
  validatePackageName,
@@ -8702,6 +8783,7 @@ export {
8702
8783
  validateTrackName,
8703
8784
  validateUploadFile,
8704
8785
  validateVersionCode,
8786
+ waitForBundleProcessing,
8705
8787
  watchVitalsWithAutoHalt,
8706
8788
  wordDiff,
8707
8789
  writeAuditLog,