project-auto-wizard 0.14.0 → 0.15.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (64) hide show
  1. package/README.ja.md +3 -1
  2. package/README.ko.md +3 -1
  3. package/README.md +4 -2
  4. package/README.zh-CN.md +3 -1
  5. package/package.json +1 -1
  6. package/payload/config/breaking-changes.json +31 -5
  7. package/payload/config/wizard-prompts.yml +0 -4
  8. package/payload/scripts/changelog_manager.py +8 -8
  9. package/payload/scripts/messages.py +460 -24
  10. package/payload/scripts/version_manager.py +102 -73
  11. package/payload/version.yml.template +2 -2
  12. package/payload/workflows/common/PROJECT-COMMON-AI-PR-SUMMARY.yaml +9 -4
  13. package/payload/workflows/common/PROJECT-COMMON-AUTO-CHANGELOG-CONTROL.yaml +62 -30
  14. package/payload/workflows/common/PROJECT-COMMON-README-VERSION-UPDATE.yaml +96 -44
  15. package/payload/workflows/common/PROJECT-COMMON-RELEASE-PUBLISH.yaml +79 -35
  16. package/payload/workflows/common/PROJECT-COMMON-VERSION-CONTROL.yaml +71 -35
  17. package/payload/workflows/flutter/PROJECT-FLUTTER-ANDROID-FIREBASE-CICD.yaml +24 -8
  18. package/payload/workflows/flutter/PROJECT-FLUTTER-ANDROID-PLAYSTORE-CICD.yaml +29 -10
  19. package/payload/workflows/flutter/PROJECT-FLUTTER-ANDROID-SELFHOSTED-CICD.yaml +57 -23
  20. package/payload/workflows/flutter/PROJECT-FLUTTER-ANDROID-TEST-APK.yaml +155 -72
  21. package/payload/workflows/flutter/PROJECT-FLUTTER-APP-BUILD-TRIGGER.yaml +49 -20
  22. package/payload/workflows/flutter/PROJECT-FLUTTER-CI.yaml +162 -62
  23. package/payload/workflows/flutter/PROJECT-FLUTTER-IOS-TEST-TESTFLIGHT.yaml +184 -87
  24. package/payload/workflows/flutter/PROJECT-FLUTTER-IOS-TESTFLIGHT.yaml +38 -15
  25. package/payload/workflows/go/PROJECT-GO-CI.yaml +14 -5
  26. package/payload/workflows/go/PROJECT-GO-PR-PREVIEW.yaml +375 -120
  27. package/payload/workflows/go/PROJECT-GO-SIMPLE-CICD.yaml +9 -4
  28. package/payload/workflows/python/PROJECT-PYTHON-CI.yaml +12 -4
  29. package/payload/workflows/python/PROJECT-PYTHON-PR-PREVIEW.yaml +375 -120
  30. package/payload/workflows/python/PROJECT-PYTHON-SIMPLE-CICD.yaml +9 -4
  31. package/payload/workflows/react/PROJECT-REACT-CI.yaml +38 -9
  32. package/payload/workflows/react/PROJECT-REACT-CICD.yaml +19 -5
  33. package/payload/workflows/spring/PROJECT-SPRING-CI.yml +71 -35
  34. package/payload/workflows/spring/server-deploy/PROJECT-SPRING-NONSTOP-NGINX-CICD.yaml +9 -6
  35. package/payload/workflows/spring/server-deploy/PROJECT-SPRING-NONSTOP-TRAEFIK-CICD.yaml +7 -4
  36. package/payload/workflows/spring/server-deploy/PROJECT-SPRING-PR-PREVIEW.yaml +425 -144
  37. package/payload/workflows/spring/server-deploy/PROJECT-SPRING-SIMPLE-CICD.yaml +7 -4
  38. package/src/cli/args.js +17 -7
  39. package/src/commands/doctor.js +16 -0
  40. package/src/commands/dry-run.js +10 -1
  41. package/src/commands/full.js +5 -2
  42. package/src/commands/interactive.js +4 -1
  43. package/src/commands/status.js +14 -1
  44. package/src/core/copy/readme.js +58 -2
  45. package/src/core/copy/simple.js +31 -0
  46. package/src/core/copy/workflows.js +2 -2
  47. package/src/core/deploy-style.js +1 -1
  48. package/src/core/detect.js +3 -2
  49. package/src/core/types.js +15 -8
  50. package/src/core/version-yml.js +52 -6
  51. package/src/i18n/catalog/en/cli.js +1 -0
  52. package/src/i18n/catalog/en/commands.js +9 -0
  53. package/src/i18n/catalog/en/copy.js +1 -0
  54. package/src/i18n/catalog/en/core2.js +3 -0
  55. package/src/i18n/catalog/ko/cli.js +1 -0
  56. package/src/i18n/catalog/ko/commands.js +9 -0
  57. package/src/i18n/catalog/ko/copy.js +1 -0
  58. package/src/i18n/catalog/ko/core2.js +3 -0
  59. package/src/index.js +8 -4
  60. package/src/ui/env-plan.js +1 -1
  61. package/src/ui/prompts.js +7 -3
  62. package/src/ui/summary.js +1 -1
  63. package/payload/workflows/next/PROJECT-NEXT-CI.yaml +0 -241
  64. package/payload/workflows/next/PROJECT-NEXT-CICD.yaml +0 -330
@@ -75,8 +75,8 @@ def _version_yml_candidates(version_yml):
75
75
  return candidates
76
76
 
77
77
 
78
- def get_language(version_yml="version.yml"):
79
- """Resolve the message language: env -> version.yml -> default.
78
+ def _resolve_language(version_yml="version.yml"):
79
+ """(language, ignored): the resolved language and the unsupported value that was skipped on the way ('' if none).
80
80
 
81
81
  Same rules as the CLI (src/i18n): values are normalized and only supported ones count.
82
82
  Unlike the CLI, an unsupported env value is ignored instead of aborting, because a
@@ -84,7 +84,8 @@ def get_language(version_yml="version.yml"):
84
84
  non-UTF-8 version.yml is skipped; the first file that has a `language:` line decides."""
85
85
  env = normalize_language(os.environ.get(LANG_ENV))
86
86
  if env in SUPPORTED:
87
- return env
87
+ return env, ""
88
+ ignored = env
88
89
  saved = ""
89
90
  for path in _version_yml_candidates(version_yml):
90
91
  try:
@@ -96,7 +97,14 @@ def get_language(version_yml="version.yml"):
96
97
  # A file without a language line says nothing; keep looking (monorepo subfolder copies etc.)
97
98
  if saved:
98
99
  break
99
- return saved if saved in SUPPORTED else DEFAULT
100
+ if saved in SUPPORTED:
101
+ return saved, ignored
102
+ return DEFAULT, ignored or saved
103
+
104
+
105
+ def get_language(version_yml="version.yml"):
106
+ """Resolve the message language: env -> version.yml -> default."""
107
+ return _resolve_language(version_yml)[0]
100
108
 
101
109
 
102
110
  def template(key, lang=None):
@@ -147,7 +155,11 @@ def main(argv):
147
155
  print(json.dumps(dump(argv[1]), ensure_ascii=False))
148
156
  return 0
149
157
  if argv == ["lang"]:
150
- print(get_language())
158
+ lang, ignored = _resolve_language()
159
+ if ignored:
160
+ # stdout stays the bare language code (callers capture it); the notice goes to stderr
161
+ print(t("lang.fallback", lang, value=ignored, lang_code=lang, supported=", ".join(SUPPORTED)), file=sys.stderr)
162
+ print(lang)
151
163
  return 0
152
164
  print("usage: messages.py get KEY [name=value ...] | dump PREFIX | lang", file=sys.stderr)
153
165
  return 2
@@ -412,7 +424,6 @@ EN = {
412
424
  "cibuild.node_deps_done": "✅ Dependencies installed",
413
425
  "cibuild.node_no_test_script": "::notice::No test script in package.json, skipping tests",
414
426
  "cibuild.node_test_run": "🧪 Running npm test: {script}",
415
- "cibuild.node_build_start_next": "🔨 Starting Next.js build...",
416
427
  "cibuild.node_build_start": "🔨 Starting build...",
417
428
  "cibuild.node_build_project": "Project: {project}",
418
429
  "cibuild.node_build_node": "Node.js: {node}",
@@ -422,8 +433,6 @@ EN = {
422
433
  "cibuild.node_build_next_dir": " - .next/ folder created",
423
434
  "cibuild.node_errlog_title": "❌ Build failed - error log",
424
435
  "cibuild.node_errlog_missing": "Error log file not found.",
425
- "cibuild.node_result_next_ok": "🎉 Next.js build complete!",
426
- "cibuild.node_result_next_fail": "❌ Next.js build failed",
427
436
  "cibuild.node_result_ok": "🎉 Build workflow complete!",
428
437
  "cibuild.node_result_fail": "❌ Build workflow failed",
429
438
  "cibuild.node_result_title": "📊 Build result:",
@@ -432,15 +441,18 @@ EN = {
432
441
  "cibuild.node_result_status": " 🆙 Build status: {status}",
433
442
  "cibuild.node_result_branch": " 🌿 Branch: {branch}",
434
443
  "cibuild.node_result_commit": " 📝 Commit: {sha}",
435
- "cibuild.node_result_time": " 🕐 Time: {time}",
444
+ "cibuild.node_result_time": " ⏰ Verified at: {time}",
436
445
  "cibuild.node_all_ok": "✅ All steps completed successfully.",
437
446
  "cibuild.node_error_occurred": "❌ An error occurred during the build.",
438
447
  "cibuild.node_log_hint": "💡 Download the 'build-log' artifact from the Actions tab to see the full log.",
448
+ "cibuild.node_result_status_not_run": " 🆙 Build status: not run (an earlier step failed)",
449
+ "cibuild.node_build_not_run": "❌ The build did not run because an earlier step failed (for example, the tests).",
450
+ "cibuild.node_build_not_run_hint": "💡 Check the log of the failed step above. There is no 'build-log' artifact for this run.",
439
451
  "cibuild.gate_results": "needs results: {results}",
440
452
  "cibuild.gate_failed": "Some jobs failed or were cancelled.",
441
453
  # --- cicd ---
442
454
  "cicd.precheck_secret_title": "Missing required Secret",
443
- "cicd.precheck_secret_body": "GitHub Secrets not registered:{missing} — add them under Settings → Secrets and variables → Actions",
455
+ "cicd.precheck_secret_body": "Required GitHub Secrets are empty:{missing} — add them under Settings → Secrets and variables → Actions",
444
456
  "cicd.precheck_dockerfile_title": "Dockerfile not found",
445
457
  "cicd.precheck_dockerfile_body": "{path} does not exist. This workflow deploys a Docker image, so a Dockerfile is required (delete this workflow file if you do not deploy to a server)",
446
458
  "cicd.precheck_ok": "✅ Pre-check passed: all required Secrets and the Dockerfile are present",
@@ -467,7 +479,6 @@ EN = {
467
479
  "cicd.config_port": " - Port: {port}",
468
480
  "cicd.config_image": " - Docker image: {image}",
469
481
  "cicd.pull_image": "⬇️ Pulling Docker image: {image}",
470
- "cicd.pull_image_short": "⬇️ Pulling Docker image...",
471
482
  "cicd.container_check": "🧹 Checking whether container {container} exists...",
472
483
  "cicd.container_exists": "⚠️ Container {container} exists. Stopping and removing it...",
473
484
  "cicd.container_removed": "✅ Container {container} removed.",
@@ -516,7 +527,7 @@ EN = {
516
527
  "fastlane.play_deploy": "Play deploy: DEPLOY_MODE={deploy_mode} -> track={track}, release_status={release_status}",
517
528
  # --- flutter_a ---
518
529
  "flutter_a.precheck_missing_title": "Missing required Secret",
519
- "flutter_a.precheck_missing_body": "GitHub Secrets not registered:{missing} - register them under Settings → Secrets and variables → Actions",
530
+ "flutter_a.precheck_missing_body": "Required GitHub Secrets are empty:{missing} — register them under Settings → Secrets and variables → Actions",
520
531
  "flutter_a.precheck_passed": "✅ Pre-check passed: all required Secrets are present",
521
532
  "flutter_a.debug_keystore_empty": "The DEBUG_KEYSTORE Secret is empty, so the build is signed with the runner's default debug key (the signature differs per build)",
522
533
  "flutter_a.debug_keystore_created": "Debug Keystore created (signed with DEBUG_KEYSTORE)",
@@ -882,6 +893,9 @@ EN = {
882
893
  "wf_changelog.merge_confirmed": "PR #{pr} merge confirmed (elapsed {elapsed}s)",
883
894
  "wf_changelog.merge_timeout": "Could not confirm the merge of PR #{pr} within {max}s — skipping the automatic RELEASE-PUBLISH trigger. If WORKFLOW_PAT is registered the normal path proceeds; otherwise run RELEASE-PUBLISH manually via workflow_dispatch if needed.",
884
895
  "wf_changelog.release_publish_triggered": "RELEASE-PUBLISH workflow_dispatch trigger requested (works without WORKFLOW_PAT)",
896
+ # --- lang ---
897
+ "lang.fallback": "Unsupported language '{value}' - falling back to '{lang_code}' (supported: {supported})",
898
+
885
899
  # --- wf_preview ---
886
900
  "wf_preview.chk_deleted_3": "3. Check that the branch has not been deleted",
887
901
  "wf_preview.chk_helper_exists": "1. Check that the Issue Helper comment exists",
@@ -963,8 +977,10 @@ EN = {
963
977
  "wf_preview.precheck_dockerfile_body": "{path} does not exist. This workflow deploys a Docker image, so a Dockerfile is required (delete this workflow file if you do not deploy to a server)",
964
978
  "wf_preview.precheck_dockerfile_title": "Dockerfile not found",
965
979
  "wf_preview.precheck_ok": "✅ Pre-check passed: all required Secrets and the Dockerfile are present",
966
- "wf_preview.precheck_secret_body": "GitHub secrets not registered:{missing} — add them under Settings → Secrets and variables → Actions",
980
+ "wf_preview.precheck_secret_body": "Required GitHub Secrets are empty:{missing} — add them under Settings → Secrets and variables → Actions",
967
981
  "wf_preview.precheck_secret_title": "Missing required secrets",
982
+ "wf_preview.precheck_skip_body": "Preview deploy secrets are not registered:{missing} — no preview could have been deployed, so there is nothing to remove",
983
+ "wf_preview.precheck_skip_title": "Preview cleanup skipped",
968
984
  "wf_preview.r_container_absent": "❌ Container not found",
969
985
  "wf_preview.r_container_confirmed": "✅ Container confirmed running",
970
986
  "wf_preview.r_container_exited": "❌ Container exited abnormally!",
@@ -1054,6 +1070,7 @@ EN = {
1054
1070
  "wf_preview.title_pr_deployed": "## ✅ PR Preview deployed!",
1055
1071
  "wf_preview.title_pr_failed": "## ❌ PR Preview deployment failed!",
1056
1072
  "wf_preview.title_running": "## ✅ Preview environment is running",
1073
+ "wf_preview.r_preview_url": "🌐 Preview URL: {url}",
1057
1074
  # --- wf_readme ---
1058
1075
  "wf_readme.hint_first_example": "## Latest Version : v1.0.0 (2025-08-15)",
1059
1076
  "wf_readme.default_heading": "Latest Version",
@@ -1076,6 +1093,7 @@ EN = {
1076
1093
  # --- wf_spring_ci ---
1077
1094
  "wf_spring_ci.status_ok": "✅ Success",
1078
1095
  "wf_spring_ci.status_fail": "❌ Failed",
1096
+ "wf_spring_ci.status_not_run": "⏸️ Not run (an earlier step failed)",
1079
1097
  "wf_spring_ci.err_compile_header": "## 🚨 Compile errors",
1080
1098
  "wf_spring_ci.err_compile_missing": "Could not find the error log.",
1081
1099
  "wf_spring_ci.err_test_header": "## 🧪 Test failures",
@@ -1096,7 +1114,6 @@ EN = {
1096
1114
  "wf_spring_ci.fix_error": "- Fix the code based on the error messages",
1097
1115
  "wf_spring_ci.fix_test": "- If tests failed, run `./gradlew test` to run them locally",
1098
1116
  "wf_spring_ci.footer": "*🤖 Generated automatically by GitHub Actions - {time}*",
1099
- "wf_spring_ci.date_locale": "en-US",
1100
1117
  "wf_spring_ci.check_summary_success": "The build verification succeeded.",
1101
1118
  "wf_spring_ci.check_summary_failure": "The build verification failed.",
1102
1119
  "wf_spring_ci.check_compile": "Compile: {status}",
@@ -1208,10 +1225,217 @@ EN = {
1208
1225
  "wf_spring_deploy.traefik_hc_timeout": "❌ Health check timed out ({sec}s)",
1209
1226
  "wf_spring_deploy.traefik_logs_header": "🔍 Last 200 log lines of {name}:",
1210
1227
  "wf_spring_deploy.traefik_done": "✅ Zero-downtime deploy complete. active={name}",
1228
+ "wf_spring_deploy.traefik_active": "🎨 active={active} → new={new}, old={old}",
1229
+ "wf_spring_deploy.nginx_colors": "🎨 Blue={blue} | Green={green}",
1230
+ "wf_spring_deploy.nginx_conf_path": "🔧 Nginx config: {path}",
1231
+ "wf_spring_deploy.nginx_reload": "🔄 nginx reload",
1211
1232
  # --- wf_version ---
1212
1233
  "wf_version.release_publish_triggered": "RELEASE-PUBLISH workflow_dispatch trigger requested (works without WORKFLOW_PAT, recovers version drift automatically)",
1213
1234
  "wf_version.backmerge_conflict": "Could not automatically merge {prod} into {dev} (conflict). Merge it manually before the next release PR: {manual}",
1214
1235
  "wf_version.backmerge_push_failed": "Could not push to {dev} (branch protection, etc.). Merge it manually before the next release PR: {manual}",
1236
+ # --- version_manager ---
1237
+ "version_manager.err_yml_missing": "ERROR: version.yml not found",
1238
+ "version_manager.warn_code_missing": "WARNING: version_code field missing, adding default value 1",
1239
+ "version_manager.warn_code_regress": "WARNING: version_code {new_code} is lower than current {current} — writing anyway (regression?)",
1240
+ "version_manager.warn_version_missing": "WARNING: version field missing in version.yml, adding it",
1241
+ "version_manager.warn_spring_no_version": "WARNING: spring: {pom} has no project <version> (inherited from parent?) — skipping",
1242
+ "version_manager.warn_spring_property": "WARNING: spring: {pom} <version> is a property ({version}) — skipping",
1243
+ "version_manager.updated": "updated: {path}",
1244
+ "version_manager.warn_spring_no_files": "WARNING: spring: no build.gradle(.kts) or pom.xml found under {dir} — skipping",
1245
+ "version_manager.warn_spring_no_gradle_line": "WARNING: spring: no `version = '...'` line in {file} — skipping",
1246
+ "version_manager.pubspec_ahead": "pubspec.yaml build number {build} is ahead of version_code {code} — adopting it",
1247
+ "version_manager.warn_flutter_missing": "WARNING: flutter: {target} not found — skipping",
1248
+ "version_manager.warn_target_missing": "WARNING: {target} not found — skipping",
1249
+ "version_manager.warn_python_no_version": "WARNING: python: no version in pyproject.toml [project]/[tool.poetry] or setup.py under {dir} — skipping",
1250
+ "version_manager.skipped_plist": "skipped: {file} — CFBundleShortVersionString references a build variable",
1251
+ "version_manager.warn_rn_ios_missing": "WARNING: react-native: {dir} not found — skipping",
1252
+ "version_manager.warn_rn_gradle_missing": "WARNING: react-native: {file} not found — skipping",
1253
+ "version_manager.warn_rn_no_targets": "WARNING: react-native: no target files found under {dir}",
1254
+ "version_manager.warn_unknown_type": "WARNING: unknown project type: {type} — skipping",
1255
+ "version_manager.err_type": "ERROR: {type}: {error}",
1256
+ "version_manager.readme_updated": "README.md version line -> v{version}",
1257
+ "version_manager.warn_read_failed": "WARNING: failed reading project file for {type}: {error}",
1258
+ "version_manager.sync_check": "Version sync check",
1259
+ "version_manager.sync_yml_version": " version.yml: {version}",
1260
+ "version_manager.sync_project_version": " project file: {version}",
1261
+ "version_manager.sync_mismatch": "Version mismatch detected, syncing to higher version: {version}",
1262
+ "version_manager.warn_format_invalid": "WARNING: version format invalid, cannot sync",
1263
+ "version_manager.sync_reconciled": "Version files updated to match version.yml: {version}",
1264
+ "version_manager.sync_ok": "Version already in sync: {version}",
1265
+ "version_manager.err_invalid_version": "ERROR: invalid version format: {version}",
1266
+ "version_manager.err_invalid_version_xyz": "ERROR: invalid version format: {version} (must be x.y.z)",
1267
+ "version_manager.err_generic": "ERROR: {error}",
1268
+ "version_manager.err_no_types_sync": "ERROR: version.yml has no readable project_types — cannot sync project files",
1269
+ "version_manager.err_no_types_check": "ERROR: version.yml has no readable project_types — cannot sync versions",
1270
+ "version_manager.err_write_failed": "failed to write version {version} to version.yml",
1271
+ "version_manager.err_not_json": "{target} is not valid JSON ({error}) — cannot write version",
1272
+ "version_manager.err_sync_failed": "project file sync failed for: {types}",
1273
+ # --- changelog_engine ---
1274
+ "changelog.engine_bump_failed": "bump AI assist failed: {error}",
1275
+ "changelog.engine_bump_copilot_failed": "bump AI assist (copilot) failed: {error}",
1276
+ "changelog.engine_user_api_empty": "user-api failed: empty content in response",
1277
+ "changelog.engine_user_api_failed": "user-api failed: {error}",
1278
+ "changelog.engine_copilot_invalid": "copilot failed: empty or not in the requested Markdown format",
1279
+ "changelog.engine_copilot_failed": "copilot failed: {error}",
1280
+ "changelog.engine_copilot_exit": "copilot exited with {code}: {detail}",
1281
+ "changelog.output_write_failed": "output write failed: {error}",
1282
+ # --- wf_common ---
1283
+ "wf_common.copilot_ai_option": "copilot_ai option: {copilot_ai}",
1284
+ "wf_common.semver_auto_option": "semver_auto option: {semver_auto}",
1285
+ "wf_common.bump_level": "bump level: {bump}",
1286
+ "wf_common.version_bump_failed": "version bump failed",
1287
+ "wf_common.no_changes": "no changes to commit",
1288
+ "wf_common.push_attempt": "push attempt {retry_count}/{max_retries}...",
1289
+ "wf_common.push_failed_syncing": "push failed, syncing with remote...",
1290
+ "wf_common.rebase_ok": "rebase ok, retrying push...",
1291
+ "wf_common.rebase_failed": "rebase failed, manual conflict resolution required",
1292
+ "wf_common.push_gave_up": "push failed after {max_retries} attempts",
1293
+ "wf_common.readme_conflict_resolved": "README.md conflicted with a concurrent update - kept the remote copy and reapplied the version line",
1294
+ # --- wf_aisum ---
1295
+ "wf_aisum.expected_version": "expected next version: {version} (current: {current_version}, mode: {mode}, bump: {bump})",
1296
+ "wf_aisum.comment_update_failed": "comment update failed — continuing (this workflow never blocks the PR)",
1297
+ "wf_aisum.comment_post_failed": "comment post failed — continuing (this workflow never blocks the PR)",
1298
+ # --- wf_changelog ---
1299
+ "wf_changelog.pr_not_open": "PR #{pr_number} is already {state} — skipping the release pipeline",
1300
+ "wf_changelog.pr_state": "PR #{pr_number} state: {state}",
1301
+ "wf_changelog.commits_to_summarize": "commits to summarize: {n}",
1302
+ "wf_changelog.version_raised": "confirmed version raised: {head_version} -> {new_version} ({bump} from {main_branch} {main_version})",
1303
+ "wf_changelog.version_reuse_unreleased": "version already confirmed and not yet released — reusing {new_version} ({main_branch} is {main_version})",
1304
+ "wf_changelog.version_reuse_previous": "version already confirmed by a previous run — reusing {new_version} (no re-increment)",
1305
+ "wf_changelog.version_confirmed": "release version confirmed: {new_version} ({bump})",
1306
+ "wf_changelog.summary_engine": "summary engine: {engine_line}",
1307
+ "wf_changelog.comment_updated": "summary comment updated (#{comment_id})",
1308
+ "wf_changelog.comment_update_failed": "comment update failed — continuing (this workflow never blocks the release)",
1309
+ "wf_changelog.comment_posted": "summary comment posted",
1310
+ "wf_changelog.comment_post_failed": "comment post failed — continuing (this workflow never blocks the release)",
1311
+ "wf_changelog.pr_closed_skip_docs": "PR is already {pr_state} — not pushing release docs",
1312
+ "wf_changelog.docs_pushed": "release docs pushed to {head_branch}",
1313
+ "wf_changelog.pr_already_merged": "PR #{pr_number} is already merged",
1314
+ "wf_changelog.automerge_enabled": "automerge enabled: {subject}",
1315
+ "wf_changelog.automerge_unavailable": "automerge unavailable — merged directly: {subject}",
1316
+ "wf_changelog.merge_retry": "merge attempt {attempt}/{max_attempts} failed — retrying in {wait}s",
1317
+ "wf_changelog.merge_gave_up": "PR merge failed after {max_attempts} attempts (allow_merge_commit={allow_merge_commit}) — check branch protection rules, required checks, and token permissions",
1318
+ # --- wf_readme ---
1319
+ "wf_readme.not_found": "README.md not found — nothing to update, skipping",
1320
+ "wf_readme.read_version_failed": "failed to read the current version",
1321
+ "wf_readme.update_failed": "README.md version update failed",
1322
+ "wf_readme.err_type": " error type: {error_type}",
1323
+ "wf_readme.err_current_line": " current version line: {version_line}",
1324
+ "wf_readme.err_header": " extracted header: {header_part}",
1325
+ "wf_readme.err_new_text": " new version text: {version_text}",
1326
+ "wf_readme.hint_formats": "Make sure the README version line matches one of:",
1327
+ "wf_readme.hint_notes": "Notes:",
1328
+ "wf_readme.hint_no_bold": " - no markdown bold (**) characters",
1329
+ "wf_readme.hint_no_regex": " - no regex special characters (*, [, ], ^, $)",
1330
+ "wf_readme.hint_after_colon": " - the version must come right after the colon (:)",
1331
+ "wf_readme.text_with_date": "version text with date: {version_text}",
1332
+ "wf_readme.text": "version text: {version_text}",
1333
+ "wf_readme.line_found": "version line found: {version_line}",
1334
+ "wf_readme.line_inserting": "no version line found — inserting a new one",
1335
+ "wf_readme.line_inserted": "default version line inserted: {version_text}",
1336
+ "wf_readme.warn_bold": "warning: the version line contains markdown bold (**) characters",
1337
+ "wf_readme.warn_current_line": " current line: {version_line}",
1338
+ "wf_readme.warn_may_break": " this may break the version update",
1339
+ "wf_readme.marker_added": "auto-update marker comment added",
1340
+ "wf_readme.updated_line_detail": " updated line: {updated_line}",
1341
+ "wf_readme.line_updated": "version line updated: {version_text}",
1342
+ "wf_readme.no_changes": "no changes in README.md",
1343
+ "wf_readme.pushed": "README.md version update pushed",
1344
+ "wf_readme.trunk_skip": "trunk-based push: RELEASE-PUBLISH updates the README and dispatches this workflow, skipping",
1345
+ "wf_readme.conflict_skip_same": "remote README.md already shows v{version}, skipping",
1346
+ "wf_readme.conflict_skip_stale": "remote is already at v{remote_version} (this run had v{version}), skipping the stale README update",
1347
+ "wf_readme.err_no_colon": "header extraction failed - no colon (:) found",
1348
+ "wf_readme.err_sed": "sed command failed - {error}",
1349
+ "wf_readme.err_sed_unknown": "unknown sed error",
1350
+ "wf_readme.err_verify": "version replacement verification failed",
1351
+ # --- wf_release ---
1352
+ "wf_release.branch_mode": "branch mode: {mode}",
1353
+ "wf_release.gate_open": "release gate open (mode={mode}, event={event})",
1354
+ "wf_release.gate_closed": "not a release-confirm push in pr-flow mode — skipping",
1355
+ "wf_release.drift_skipped": "drift guard skipped (no version.yml version or no tag yet)",
1356
+ "wf_release.drift_error": "version.yml({file_version}) is ahead of the newest tag({latest_tag}) but no release was published — this version will never reach npm. Recover with: Actions → PROJECT-RELEASE-PUBLISH → Run workflow (workflow_dispatch bypasses this gate).",
1357
+ "wf_release.drift_ok": "drift guard ok (version.yml={file_version}, latest tag={latest_tag})",
1358
+ "wf_release.head_is_docs_commit": "HEAD is already this workflow's release docs commit — skipping re-increment (idempotent re-run)",
1359
+ "wf_release.collect_since": "collecting commits since {last_tag}",
1360
+ "wf_release.collect_all": "no previous tag — collecting the full history",
1361
+ "wf_release.release_version": "release version: {new_version} ({bump})",
1362
+ "wf_release.docs_pushed": "release docs pushed",
1363
+ "wf_release.read_version_failed": "failed to read version",
1364
+ "wf_release.tag_exists": "tag v{version} already exists — skipping tag push",
1365
+ "wf_release.release_exists": "release v{version} already exists — nothing to publish",
1366
+ "wf_release.publishing": "publishing release v{version}",
1367
+ "wf_release.tag_pushed": "tag v{version} pushed",
1368
+ "wf_release.notes_assembled": "release notes assembled ({n} bytes)",
1369
+ "wf_release.published": "GitHub Release v{version} published",
1370
+ # --- wf_version ---
1371
+ "wf_version.trunk_skip": "trunk-based mode detected — RELEASE-PUBLISH owns version bumping, skipping",
1372
+ "wf_version.confirm_skip": "release-confirm commit detected (chore(release):) — skipping safety-net bump",
1373
+ "wf_version.release_merge_skip": "release merge detected (push contains a version.yml change) — skipping safety-net bump",
1374
+ "wf_version.direct_push": "direct push to {main_branch} detected — running safety-net version bump",
1375
+ "wf_version.read_current_failed": "failed to read current version",
1376
+ "wf_version.current_version": "current version: {current_version}",
1377
+ "wf_version.new_version": "new version: {new_version}",
1378
+ "wf_version.project_types": "project types: {project_types}",
1379
+ "wf_version.yml_not_found": "version.yml not found",
1380
+ "wf_version.commits_since": "commits since {last_tag}: {n}",
1381
+ "wf_version.no_changes_synced": "no changes to commit (already in sync)",
1382
+ "wf_version.bump_pushed": "version bump commit pushed",
1383
+ "wf_version.commit_failed": "commit failed",
1384
+ "wf_version.no_develop": "branch {develop_branch} not found — nothing to back-merge",
1385
+ "wf_version.already_contains": "{develop_branch} already contains {main_branch}",
1386
+ "wf_version.backmerged": "safety-net bump v{new_version} merged into {develop_branch}",
1387
+ "wf_version.push_retry": "push attempt {attempt} failed — retrying",
1388
+ "wf_version.finished": "version-control workflow finished",
1389
+ "wf_version.sum_skipped": " skipped (release merge / trunk-based): {skip}",
1390
+ "wf_version.sum_previous": " previous version: {current_version}",
1391
+ "wf_version.sum_new": " new version: {new_version}",
1392
+ "wf_version.sum_branch": " branch: {ref_name}",
1393
+ # --- wf_flutter ---
1394
+ "wf_flutter.env_file_created": "✅ {file} file created",
1395
+ "wf_flutter.dotenv_created": ".env file created",
1396
+ "wf_flutter.dart_define_prepared": "dart-define file prepared",
1397
+ "wf_flutter.google_services_created": "✅ google-services.json created",
1398
+ "wf_flutter.google_services_skipped": "ℹ️ GOOGLE_SERVICES_JSON secret not provided, skipping",
1399
+ "wf_flutter.flutter_setup_done_ok": "✅ Flutter setup completed",
1400
+ "wf_flutter.flutter_setup_done": "Flutter setup completed",
1401
+ "wf_flutter.deps_installed_ok": "✅ Dependencies installed",
1402
+ "wf_flutter.deps_installed": "Dependencies installed",
1403
+ "wf_flutter.gradle_perm_ok": "✅ Gradle wrapper permissions set",
1404
+ "wf_flutter.gradle_perm": "Gradle wrapper permissions set",
1405
+ "wf_flutter.java_setup_done_ok": "✅ Java setup completed",
1406
+ "wf_flutter.java_setup_done": "Java setup completed",
1407
+ "wf_flutter.apk_built_ok": "✅ APK built",
1408
+ "wf_flutter.apk_built": "APK built",
1409
+ "wf_flutter.apk_renamed_ok": "✅ APK renamed to {name}",
1410
+ "wf_flutter.apk_renamed": "APK renamed to {name}",
1411
+ "wf_flutter.repo_checked_out": "Repository checked out",
1412
+ "wf_flutter.keystore_from_debug": "Keystore created from DEBUG_KEYSTORE",
1413
+ "wf_flutter.key_properties_created": "key.properties created",
1414
+ "wf_flutter.repo_checked_out_deploy": "Repository checked out for deploy",
1415
+ "wf_flutter.smb_deps_installed": "SMB and jq dependencies installed",
1416
+ "wf_flutter.download_listed": "Downloaded structure listed",
1417
+ "wf_flutter.apk_file_found": "APK file found: {file}",
1418
+ "wf_flutter.smb_uploading": "Uploading APK file {name} to SMB...",
1419
+ "wf_flutter.smb_path": "SMB Path: {path}",
1420
+ "wf_flutter.smb_uploaded": "APK uploaded to SMB",
1421
+ "wf_flutter.history_loaded": "Downloaded or initialized {file}",
1422
+ "wf_flutter.history_updated": "Updated {file} with new build info",
1423
+ "wf_flutter.history_uploaded": "Updated {file} uploaded to SMB",
1424
+ "wf_flutter.secrets_xcconfig_created_ok": "✅ Secrets.xcconfig created",
1425
+ "wf_flutter.secrets_xcconfig_empty": "ℹ️ Empty Secrets.xcconfig created (no secrets provided)",
1426
+ "wf_flutter.secrets_xcconfig_created": "Secrets.xcconfig created",
1427
+ "wf_flutter.xcode_platform_check": "=== iPhoneOS.platform check ===",
1428
+ "wf_flutter.xcode_platform_exists": "iPhoneOS.platform EXISTS",
1429
+ "wf_flutter.xcode_platform_missing": "iPhoneOS.platform NOT FOUND",
1430
+ "wf_flutter.xcode_install_pkgs": "=== Installing MobileDevice packages ===",
1431
+ "wf_flutter.xcode_license": "=== Accepting Xcode license ===",
1432
+ "wf_flutter.xcode_init": "=== Initializing Xcode components ===",
1433
+ "wf_flutter.xcode_download": "=== Downloading iOS platform ===",
1434
+ "wf_flutter.ipa_found": "📦 Found IPA at: {path}",
1435
+ "wf_flutter.release_notes_heading": "📝 Release Notes:",
1436
+ "wf_flutter.working_dir": "🔧 Working directory: {dir}",
1437
+ "wf_flutter.run_number": "🔍 GitHub Run Number: {number}",
1438
+ "wf_flutter.ci_analyze_only": " Analyze Only: {value}",
1215
1439
  }
1216
1440
 
1217
1441
  KO = {
@@ -1470,7 +1694,6 @@ KO = {
1470
1694
  "cibuild.node_deps_done": "✅ 의존성 설치 완료",
1471
1695
  "cibuild.node_no_test_script": "::notice::package.json에 test 스크립트가 없어 테스트를 건너뜁니다",
1472
1696
  "cibuild.node_test_run": "🧪 npm test 실행: {script}",
1473
- "cibuild.node_build_start_next": "🔨 Next.js 빌드 시작...",
1474
1697
  "cibuild.node_build_start": "🔨 빌드 시작...",
1475
1698
  "cibuild.node_build_project": "프로젝트: {project}",
1476
1699
  "cibuild.node_build_node": "Node.js: {node}",
@@ -1480,8 +1703,6 @@ KO = {
1480
1703
  "cibuild.node_build_next_dir": " - .next/ 폴더 생성됨",
1481
1704
  "cibuild.node_errlog_title": "❌ 빌드 실패 - 에러 로그",
1482
1705
  "cibuild.node_errlog_missing": "에러 로그 파일을 찾을 수 없습니다.",
1483
- "cibuild.node_result_next_ok": "🎉 Next.js 빌드 완료!",
1484
- "cibuild.node_result_next_fail": "❌ Next.js 빌드 실패",
1485
1706
  "cibuild.node_result_ok": "🎉 빌드 워크플로우 완료!",
1486
1707
  "cibuild.node_result_fail": "❌ 빌드 워크플로우 실패",
1487
1708
  "cibuild.node_result_title": "📊 빌드 결과:",
@@ -1490,15 +1711,18 @@ KO = {
1490
1711
  "cibuild.node_result_status": " 🆙 빌드 상태: {status}",
1491
1712
  "cibuild.node_result_branch": " 🌿 브랜치: {branch}",
1492
1713
  "cibuild.node_result_commit": " 📝 커밋: {sha}",
1493
- "cibuild.node_result_time": " 🕐 시간: {time}",
1714
+ "cibuild.node_result_time": " ⏰ 검증 시간: {time}",
1494
1715
  "cibuild.node_all_ok": "✅ 모든 단계가 성공적으로 완료되었습니다.",
1495
1716
  "cibuild.node_error_occurred": "❌ 빌드 중 오류가 발생했습니다.",
1496
1717
  "cibuild.node_log_hint": "💡 Actions 탭에서 'build-log' 아티팩트를 다운로드하여 전체 로그를 확인하세요.",
1718
+ "cibuild.node_result_status_not_run": " 🆙 빌드 상태: 실행 안 됨 (이전 단계 실패)",
1719
+ "cibuild.node_build_not_run": "❌ 이전 단계(예: 테스트)가 실패하여 빌드가 실행되지 않았습니다.",
1720
+ "cibuild.node_build_not_run_hint": "💡 위에서 실패한 단계의 로그를 확인하세요. 이번 실행에는 'build-log' 아티팩트가 없습니다.",
1497
1721
  "cibuild.gate_results": "needs 결과: {results}",
1498
1722
  "cibuild.gate_failed": "실패하거나 취소된 job이 있습니다.",
1499
1723
  # --- cicd ---
1500
1724
  "cicd.precheck_secret_title": "필수 Secret 누락",
1501
- "cicd.precheck_secret_body": "등록되지 않은 GitHub Secret:{missing} — Settings → Secrets and variables → Actions에서 등록하세요",
1725
+ "cicd.precheck_secret_body": "필수 GitHub Secret이 비어 있습니다:{missing} — Settings → Secrets and variables → Actions에서 등록하세요",
1502
1726
  "cicd.precheck_dockerfile_title": "Dockerfile 없음",
1503
1727
  "cicd.precheck_dockerfile_body": "{path} 파일이 없습니다. 이 워크플로우는 Docker 이미지로 배포하므로 Dockerfile이 필요합니다 (서버 배포를 하지 않는다면 이 워크플로우 파일을 삭제하세요)",
1504
1728
  "cicd.precheck_ok": "✅ 사전 점검 통과: 필수 Secret과 Dockerfile이 모두 있습니다",
@@ -1525,7 +1749,6 @@ KO = {
1525
1749
  "cicd.config_port": " - 포트: {port}",
1526
1750
  "cicd.config_image": " - Docker 이미지: {image}",
1527
1751
  "cicd.pull_image": "⬇️ Docker 이미지 풀: {image}",
1528
- "cicd.pull_image_short": "⬇️ Docker 이미지 풀...",
1529
1752
  "cicd.container_check": "🧹 컨테이너 {container} 존재 여부 확인 중...",
1530
1753
  "cicd.container_exists": "⚠️ 컨테이너 {container} 이(가) 존재합니다. 중지 및 삭제 중...",
1531
1754
  "cicd.container_removed": "✅ 컨테이너 {container} 이(가) 삭제되었습니다.",
@@ -1574,7 +1797,7 @@ KO = {
1574
1797
  "fastlane.play_deploy": "Play 배포: DEPLOY_MODE={deploy_mode} → track={track}, release_status={release_status}",
1575
1798
  # --- flutter_a ---
1576
1799
  "flutter_a.precheck_missing_title": "필수 Secret 누락",
1577
- "flutter_a.precheck_missing_body": "등록되지 않은 GitHub Secret:{missing} — Settings → Secrets and variables → Actions에서 등록하세요",
1800
+ "flutter_a.precheck_missing_body": "필수 GitHub Secret이 비어 있습니다:{missing} — Settings → Secrets and variables → Actions에서 등록하세요",
1578
1801
  "flutter_a.precheck_passed": "✅ 사전 점검 통과: 필수 Secret이 모두 있습니다",
1579
1802
  "flutter_a.debug_keystore_empty": "DEBUG_KEYSTORE Secret이 비어 있어 러너 기본 debug 키로 서명합니다 (빌드마다 서명이 달라집니다)",
1580
1803
  "flutter_a.debug_keystore_created": "Debug Keystore created (DEBUG_KEYSTORE로 서명)",
@@ -1940,6 +2163,9 @@ KO = {
1940
2163
  "wf_changelog.merge_confirmed": "PR #{pr} 병합 확인 (경과 {elapsed}s)",
1941
2164
  "wf_changelog.merge_timeout": "PR #{pr} 병합을 {max}s 내에 확인하지 못했습니다 — RELEASE-PUBLISH 자동 트리거를 건너뜁니다. WORKFLOW_PAT이 등록되어 있다면 기존 경로로 정상 진행되며, 없다면 필요 시 RELEASE-PUBLISH를 수동으로 workflow_dispatch 하세요.",
1942
2165
  "wf_changelog.release_publish_triggered": "RELEASE-PUBLISH workflow_dispatch 트리거 요청 완료 (WORKFLOW_PAT 없이도 동작)",
2166
+ # --- lang ---
2167
+ "lang.fallback": "지원하지 않는 language 값 '{value}' - '{lang_code}'(으)로 대체합니다 (지원: {supported})",
2168
+
1943
2169
  # --- wf_preview ---
1944
2170
  "wf_preview.chk_deleted_3": "3. 브랜치가 삭제되지 않았는지 확인하세요",
1945
2171
  "wf_preview.chk_helper_exists": "1. Issue Helper 댓글이 존재하는지 확인하세요",
@@ -2021,8 +2247,10 @@ KO = {
2021
2247
  "wf_preview.precheck_dockerfile_body": "{path} 파일이 없습니다. 이 워크플로우는 Docker 이미지로 배포하므로 Dockerfile이 필요합니다 (서버 배포를 하지 않는다면 이 워크플로우 파일을 삭제하세요)",
2022
2248
  "wf_preview.precheck_dockerfile_title": "Dockerfile 없음",
2023
2249
  "wf_preview.precheck_ok": "✅ 사전 점검 통과: 필수 Secret과 Dockerfile이 모두 있습니다",
2024
- "wf_preview.precheck_secret_body": "등록되지 않은 GitHub Secret:{missing} — Settings → Secrets and variables → Actions에서 등록하세요",
2250
+ "wf_preview.precheck_secret_body": "필수 GitHub Secret이 비어 있습니다:{missing} — Settings → Secrets and variables → Actions에서 등록하세요",
2025
2251
  "wf_preview.precheck_secret_title": "필수 Secret 누락",
2252
+ "wf_preview.precheck_skip_body": "미리보기 배포용 Secret이 등록되지 않았습니다:{missing} — 배포된 미리보기가 없으므로 삭제할 것이 없습니다",
2253
+ "wf_preview.precheck_skip_title": "미리보기 정리 건너뜀",
2026
2254
  "wf_preview.r_container_absent": "❌ 컨테이너 없음",
2027
2255
  "wf_preview.r_container_confirmed": "✅ 컨테이너 실행 확인됨",
2028
2256
  "wf_preview.r_container_exited": "❌ 컨테이너 비정상 종료!",
@@ -2112,6 +2340,7 @@ KO = {
2112
2340
  "wf_preview.title_pr_deployed": "## ✅ PR Preview 배포 완료!",
2113
2341
  "wf_preview.title_pr_failed": "## ❌ PR Preview 배포 실패!",
2114
2342
  "wf_preview.title_running": "## ✅ Preview 환경 실행 중",
2343
+ "wf_preview.r_preview_url": "🌐 미리보기 URL: {url}",
2115
2344
  # --- wf_readme ---
2116
2345
  "wf_readme.hint_first_example": "## 최신 버전 : v1.0.0 (2025-08-15)",
2117
2346
  "wf_readme.default_heading": "최신 버전",
@@ -2134,6 +2363,7 @@ KO = {
2134
2363
  # --- wf_spring_ci ---
2135
2364
  "wf_spring_ci.status_ok": "✅ 성공",
2136
2365
  "wf_spring_ci.status_fail": "❌ 실패",
2366
+ "wf_spring_ci.status_not_run": "⏸️ 실행 안 됨 (이전 단계 실패)",
2137
2367
  "wf_spring_ci.err_compile_header": "## 🚨 컴파일 에러",
2138
2368
  "wf_spring_ci.err_compile_missing": "에러 로그를 찾을 수 없습니다.",
2139
2369
  "wf_spring_ci.err_test_header": "## 🧪 테스트 실패",
@@ -2154,7 +2384,6 @@ KO = {
2154
2384
  "wf_spring_ci.fix_error": "- 에러 메시지를 참고하여 코드를 수정해주세요",
2155
2385
  "wf_spring_ci.fix_test": "- 테스트가 실패한 경우 `./gradlew test` 명령어로 테스트를 실행해보세요",
2156
2386
  "wf_spring_ci.footer": "*🤖 GitHub Actions에 의해 자동 생성됨 - {time}*",
2157
- "wf_spring_ci.date_locale": "ko-KR",
2158
2387
  "wf_spring_ci.check_summary_success": "빌드 검증이 성공했습니다.",
2159
2388
  "wf_spring_ci.check_summary_failure": "빌드 검증이 실패했습니다.",
2160
2389
  "wf_spring_ci.check_compile": "컴파일: {status}",
@@ -2266,10 +2495,217 @@ KO = {
2266
2495
  "wf_spring_deploy.traefik_hc_timeout": "❌ 헬스체크 타임아웃 ({sec}초)",
2267
2496
  "wf_spring_deploy.traefik_logs_header": "🔍 {name} 최근 200줄 로그:",
2268
2497
  "wf_spring_deploy.traefik_done": "✅ 무중단 배포 완료. active={name}",
2498
+ "wf_spring_deploy.traefik_active": "🎨 활성={active} → 신규={new}, 이전={old}",
2499
+ "wf_spring_deploy.nginx_colors": "🎨 Blue={blue} | Green={green}",
2500
+ "wf_spring_deploy.nginx_conf_path": "🔧 Nginx 설정 파일: {path}",
2501
+ "wf_spring_deploy.nginx_reload": "🔄 nginx reload 실행",
2269
2502
  # --- wf_version ---
2270
- "wf_version.release_publish_triggered": "RELEASE-PUBLISH workflow_dispatch 트리거 요청 완료 (WORKFLOW_PAT 없이도 동작, 이슈 #61 드리프트 자동 복구)",
2503
+ "wf_version.release_publish_triggered": "RELEASE-PUBLISH workflow_dispatch 트리거 요청 완료 (WORKFLOW_PAT 없이도 동작, 버전 드리프트 자동 복구)",
2271
2504
  "wf_version.backmerge_conflict": "{prod}을 {dev}에 자동 병합하지 못했습니다 (충돌). 다음 릴리스 PR 전에 직접 병합하세요: {manual}",
2272
2505
  "wf_version.backmerge_push_failed": "{dev}에 push하지 못했습니다 (브랜치 보호 등). 다음 릴리스 PR 전에 직접 병합하세요: {manual}",
2506
+ # --- version_manager ---
2507
+ "version_manager.err_yml_missing": "오류: version.yml을 찾을 수 없습니다",
2508
+ "version_manager.warn_code_missing": "경고: version_code 필드가 없어 기본값 1을 추가합니다",
2509
+ "version_manager.warn_code_regress": "경고: version_code {new_code}이(가) 현재 값 {current}보다 낮습니다 — 그대로 기록합니다 (역행 여부 확인 필요)",
2510
+ "version_manager.warn_version_missing": "경고: version.yml에 version 필드가 없어 추가합니다",
2511
+ "version_manager.warn_spring_no_version": "경고: spring: {pom}에 프로젝트 <version>이 없습니다 (부모에서 상속?) — 건너뜁니다",
2512
+ "version_manager.warn_spring_property": "경고: spring: {pom}의 <version>이 속성값({version})입니다 — 건너뜁니다",
2513
+ "version_manager.updated": "수정됨: {path}",
2514
+ "version_manager.warn_spring_no_files": "경고: spring: {dir} 아래에서 build.gradle(.kts)나 pom.xml을 찾지 못했습니다 — 건너뜁니다",
2515
+ "version_manager.warn_spring_no_gradle_line": "경고: spring: {file}에 `version = '...'` 줄이 없습니다 — 건너뜁니다",
2516
+ "version_manager.pubspec_ahead": "pubspec.yaml 빌드 번호 {build}이(가) version_code {code}보다 앞서 있어 그 값을 사용합니다",
2517
+ "version_manager.warn_flutter_missing": "경고: flutter: {target}을(를) 찾을 수 없습니다 — 건너뜁니다",
2518
+ "version_manager.warn_target_missing": "경고: {target}을(를) 찾을 수 없습니다 — 건너뜁니다",
2519
+ "version_manager.warn_python_no_version": "경고: python: {dir} 아래의 pyproject.toml [project]/[tool.poetry]나 setup.py에 버전이 없습니다 — 건너뜁니다",
2520
+ "version_manager.skipped_plist": "건너뜀: {file} — CFBundleShortVersionString이 빌드 변수를 참조합니다",
2521
+ "version_manager.warn_rn_ios_missing": "경고: react-native: {dir}을(를) 찾을 수 없습니다 — 건너뜁니다",
2522
+ "version_manager.warn_rn_gradle_missing": "경고: react-native: {file}을(를) 찾을 수 없습니다 — 건너뜁니다",
2523
+ "version_manager.warn_rn_no_targets": "경고: react-native: {dir} 아래에서 대상 파일을 찾지 못했습니다",
2524
+ "version_manager.warn_unknown_type": "경고: 알 수 없는 프로젝트 타입: {type} — 건너뜁니다",
2525
+ "version_manager.err_type": "오류: {type}: {error}",
2526
+ "version_manager.readme_updated": "README.md 버전 줄 -> v{version}",
2527
+ "version_manager.warn_read_failed": "경고: {type} 프로젝트 파일을 읽지 못했습니다: {error}",
2528
+ "version_manager.sync_check": "버전 동기화 확인",
2529
+ "version_manager.sync_yml_version": " version.yml: {version}",
2530
+ "version_manager.sync_project_version": " 프로젝트 파일: {version}",
2531
+ "version_manager.sync_mismatch": "버전 불일치를 감지해 더 높은 버전으로 맞춥니다: {version}",
2532
+ "version_manager.warn_format_invalid": "경고: 버전 형식이 올바르지 않아 동기화할 수 없습니다",
2533
+ "version_manager.sync_reconciled": "version.yml 버전({version})에 맞게 버전 파일을 수정했습니다",
2534
+ "version_manager.sync_ok": "이미 버전이 일치합니다: {version}",
2535
+ "version_manager.err_invalid_version": "오류: 올바르지 않은 버전 형식: {version}",
2536
+ "version_manager.err_invalid_version_xyz": "오류: 올바르지 않은 버전 형식: {version} (x.y.z 형식이어야 합니다)",
2537
+ "version_manager.err_generic": "오류: {error}",
2538
+ "version_manager.err_no_types_sync": "오류: version.yml에서 project_types를 읽을 수 없어 프로젝트 파일을 동기화할 수 없습니다",
2539
+ "version_manager.err_no_types_check": "오류: version.yml에서 project_types를 읽을 수 없어 버전을 동기화할 수 없습니다",
2540
+ "version_manager.err_write_failed": "version.yml에 버전 {version}을(를) 기록하지 못했습니다",
2541
+ "version_manager.err_not_json": "{target}이(가) 올바른 JSON이 아닙니다 ({error}) — 버전을 기록할 수 없습니다",
2542
+ "version_manager.err_sync_failed": "프로젝트 파일 동기화 실패: {types}",
2543
+ # --- changelog_engine ---
2544
+ "changelog.engine_bump_failed": "bump AI 보조 실패: {error}",
2545
+ "changelog.engine_bump_copilot_failed": "bump AI 보조(copilot) 실패: {error}",
2546
+ "changelog.engine_user_api_empty": "user-api 실패: 응답에 내용이 없습니다",
2547
+ "changelog.engine_user_api_failed": "user-api 실패: {error}",
2548
+ "changelog.engine_copilot_invalid": "copilot 실패: 응답이 비었거나 요청한 Markdown 형식이 아닙니다",
2549
+ "changelog.engine_copilot_failed": "copilot 실패: {error}",
2550
+ "changelog.engine_copilot_exit": "copilot이 종료 코드 {code}로 끝났습니다: {detail}",
2551
+ "changelog.output_write_failed": "출력 파일 쓰기 실패: {error}",
2552
+ # --- wf_common ---
2553
+ "wf_common.copilot_ai_option": "copilot_ai 옵션: {copilot_ai}",
2554
+ "wf_common.semver_auto_option": "semver_auto 옵션: {semver_auto}",
2555
+ "wf_common.bump_level": "승격 폭: {bump}",
2556
+ "wf_common.version_bump_failed": "버전 승격에 실패했습니다",
2557
+ "wf_common.no_changes": "커밋할 변경 사항이 없습니다",
2558
+ "wf_common.push_attempt": "push 시도 {retry_count}/{max_retries}...",
2559
+ "wf_common.push_failed_syncing": "push 실패, 원격과 동기화합니다...",
2560
+ "wf_common.rebase_ok": "rebase 성공, push를 다시 시도합니다...",
2561
+ "wf_common.rebase_failed": "rebase 실패, 충돌을 직접 해결해야 합니다",
2562
+ "wf_common.push_gave_up": "push가 {max_retries}회 시도 후에도 실패했습니다",
2563
+ "wf_common.readme_conflict_resolved": "동시에 수정된 README.md 충돌을 원격 내용을 유지하고 버전 줄을 다시 반영해 해결했습니다",
2564
+ # --- wf_aisum ---
2565
+ "wf_aisum.expected_version": "예상 다음 버전: {version} (현재: {current_version}, 모드: {mode}, 승격: {bump})",
2566
+ "wf_aisum.comment_update_failed": "댓글 수정 실패 — 계속 진행합니다 (이 워크플로우는 PR을 막지 않습니다)",
2567
+ "wf_aisum.comment_post_failed": "댓글 등록 실패 — 계속 진행합니다 (이 워크플로우는 PR을 막지 않습니다)",
2568
+ # --- wf_changelog ---
2569
+ "wf_changelog.pr_not_open": "PR #{pr_number}은(는) 이미 {state} 상태입니다 — 릴리스 파이프라인을 건너뜁니다",
2570
+ "wf_changelog.pr_state": "PR #{pr_number} 상태: {state}",
2571
+ "wf_changelog.commits_to_summarize": "요약할 커밋 수: {n}",
2572
+ "wf_changelog.version_raised": "확정 버전을 올렸습니다: {head_version} -> {new_version} ({main_branch} {main_version} 기준 {bump})",
2573
+ "wf_changelog.version_reuse_unreleased": "이미 확정됐고 아직 릴리스되지 않은 버전이라 {new_version}을(를) 재사용합니다 ({main_branch}는 {main_version})",
2574
+ "wf_changelog.version_reuse_previous": "이전 실행에서 이미 확정된 버전이라 {new_version}을(를) 재사용합니다 (다시 올리지 않음)",
2575
+ "wf_changelog.version_confirmed": "릴리스 버전 확정: {new_version} ({bump})",
2576
+ "wf_changelog.summary_engine": "요약 엔진: {engine_line}",
2577
+ "wf_changelog.comment_updated": "요약 댓글을 수정했습니다 (#{comment_id})",
2578
+ "wf_changelog.comment_update_failed": "댓글 수정 실패 — 계속 진행합니다 (이 워크플로우는 릴리스를 막지 않습니다)",
2579
+ "wf_changelog.comment_posted": "요약 댓글을 등록했습니다",
2580
+ "wf_changelog.comment_post_failed": "댓글 등록 실패 — 계속 진행합니다 (이 워크플로우는 릴리스를 막지 않습니다)",
2581
+ "wf_changelog.pr_closed_skip_docs": "PR이 이미 {pr_state} 상태입니다 — 릴리스 문서를 push하지 않습니다",
2582
+ "wf_changelog.docs_pushed": "릴리스 문서를 {head_branch}에 push했습니다",
2583
+ "wf_changelog.pr_already_merged": "PR #{pr_number}은(는) 이미 병합되었습니다",
2584
+ "wf_changelog.automerge_enabled": "automerge 활성화: {subject}",
2585
+ "wf_changelog.automerge_unavailable": "automerge를 쓸 수 없어 직접 병합했습니다: {subject}",
2586
+ "wf_changelog.merge_retry": "병합 시도 {attempt}/{max_attempts} 실패 — {wait}초 후 다시 시도합니다",
2587
+ "wf_changelog.merge_gave_up": "PR 병합이 {max_attempts}회 시도 후에도 실패했습니다 (allow_merge_commit={allow_merge_commit}) — 브랜치 보호 규칙, 필수 체크, 토큰 권한을 확인하세요",
2588
+ # --- wf_readme ---
2589
+ "wf_readme.not_found": "README.md가 없습니다 — 수정할 것이 없어 건너뜁니다",
2590
+ "wf_readme.read_version_failed": "현재 버전을 읽지 못했습니다",
2591
+ "wf_readme.update_failed": "README.md 버전 수정에 실패했습니다",
2592
+ "wf_readme.err_type": " 오류 유형: {error_type}",
2593
+ "wf_readme.err_current_line": " 현재 버전 줄: {version_line}",
2594
+ "wf_readme.err_header": " 추출한 머리말: {header_part}",
2595
+ "wf_readme.err_new_text": " 새 버전 문구: {version_text}",
2596
+ "wf_readme.hint_formats": "README 버전 줄이 다음 중 하나와 같은 형식인지 확인하세요:",
2597
+ "wf_readme.hint_notes": "참고:",
2598
+ "wf_readme.hint_no_bold": " - 마크다운 굵게(**) 문자를 쓰지 마세요",
2599
+ "wf_readme.hint_no_regex": " - 정규식 특수문자(*, [, ], ^, $)를 쓰지 마세요",
2600
+ "wf_readme.hint_after_colon": " - 버전은 콜론(:) 바로 뒤에 와야 합니다",
2601
+ "wf_readme.text_with_date": "날짜 포함 버전 문구: {version_text}",
2602
+ "wf_readme.text": "버전 문구: {version_text}",
2603
+ "wf_readme.line_found": "버전 줄 발견: {version_line}",
2604
+ "wf_readme.line_inserting": "버전 줄이 없어 새로 추가합니다",
2605
+ "wf_readme.line_inserted": "기본 버전 줄을 추가했습니다: {version_text}",
2606
+ "wf_readme.warn_bold": "경고: 버전 줄에 마크다운 굵게(**) 문자가 들어 있습니다",
2607
+ "wf_readme.warn_current_line": " 현재 줄: {version_line}",
2608
+ "wf_readme.warn_may_break": " 버전 수정이 깨질 수 있습니다",
2609
+ "wf_readme.marker_added": "자동 갱신 표시 주석을 추가했습니다",
2610
+ "wf_readme.updated_line_detail": " 수정된 줄: {updated_line}",
2611
+ "wf_readme.line_updated": "버전 줄을 수정했습니다: {version_text}",
2612
+ "wf_readme.no_changes": "README.md에 변경 사항이 없습니다",
2613
+ "wf_readme.pushed": "README.md 버전 수정을 push했습니다",
2614
+ "wf_readme.trunk_skip": "trunk-based push: RELEASE-PUBLISH가 README를 갱신하고 이 워크플로우를 호출하므로 건너뜁니다",
2615
+ "wf_readme.conflict_skip_same": "원격 README.md가 이미 v{version}이라 건너뜁니다",
2616
+ "wf_readme.conflict_skip_stale": "원격이 이미 v{remote_version}입니다 (이 실행은 v{version}), 오래된 README 갱신을 건너뜁니다",
2617
+ "wf_readme.err_no_colon": "머리말 추출 실패 - 콜론(:)을 찾을 수 없습니다",
2618
+ "wf_readme.err_sed": "sed 명령 실패 - {error}",
2619
+ "wf_readme.err_sed_unknown": "알 수 없는 sed 오류",
2620
+ "wf_readme.err_verify": "버전 교체 검증에 실패했습니다",
2621
+ # --- wf_release ---
2622
+ "wf_release.branch_mode": "브랜치 모드: {mode}",
2623
+ "wf_release.gate_open": "릴리스 게이트 열림 (mode={mode}, event={event})",
2624
+ "wf_release.gate_closed": "pr-flow 모드에서 릴리스 확정 push가 아니므로 건너뜁니다",
2625
+ "wf_release.drift_skipped": "드리프트 검사 건너뜀 (version.yml 버전이 없거나 아직 태그가 없음)",
2626
+ "wf_release.drift_error": "version.yml({file_version})이(가) 최신 태그({latest_tag})보다 앞서 있지만 릴리스가 발행되지 않았습니다 — 이 버전은 npm에 배포되지 않습니다. 복구: Actions → PROJECT-RELEASE-PUBLISH → Run workflow (workflow_dispatch는 이 게이트를 우회합니다).",
2627
+ "wf_release.drift_ok": "드리프트 검사 통과 (version.yml={file_version}, 최신 태그={latest_tag})",
2628
+ "wf_release.head_is_docs_commit": "HEAD가 이미 이 워크플로우의 릴리스 문서 커밋입니다 — 버전을 다시 올리지 않습니다 (재실행 안전)",
2629
+ "wf_release.collect_since": "{last_tag} 이후 커밋을 수집합니다",
2630
+ "wf_release.collect_all": "이전 태그가 없어 전체 히스토리를 수집합니다",
2631
+ "wf_release.release_version": "릴리스 버전: {new_version} ({bump})",
2632
+ "wf_release.docs_pushed": "릴리스 문서를 push했습니다",
2633
+ "wf_release.read_version_failed": "버전을 읽지 못했습니다",
2634
+ "wf_release.tag_exists": "태그 v{version}이(가) 이미 있어 태그 push를 건너뜁니다",
2635
+ "wf_release.release_exists": "릴리스 v{version}이(가) 이미 있어 발행할 것이 없습니다",
2636
+ "wf_release.publishing": "릴리스 v{version}을(를) 발행합니다",
2637
+ "wf_release.tag_pushed": "태그 v{version}을(를) push했습니다",
2638
+ "wf_release.notes_assembled": "릴리스 노트 작성 완료 ({n} 바이트)",
2639
+ "wf_release.published": "GitHub Release v{version}을(를) 발행했습니다",
2640
+ # --- wf_version ---
2641
+ "wf_version.trunk_skip": "trunk-based 모드입니다 — 버전 승격은 RELEASE-PUBLISH가 맡으므로 건너뜁니다",
2642
+ "wf_version.confirm_skip": "릴리스 확정 커밋(chore(release):)을 감지했습니다 — 안전망 버전 승격을 건너뜁니다",
2643
+ "wf_version.release_merge_skip": "릴리스 병합을 감지했습니다 (push에 version.yml 변경 포함) — 안전망 버전 승격을 건너뜁니다",
2644
+ "wf_version.direct_push": "{main_branch}에 직접 push를 감지했습니다 — 안전망 버전 승격을 실행합니다",
2645
+ "wf_version.read_current_failed": "현재 버전을 읽지 못했습니다",
2646
+ "wf_version.current_version": "현재 버전: {current_version}",
2647
+ "wf_version.new_version": "새 버전: {new_version}",
2648
+ "wf_version.project_types": "프로젝트 타입: {project_types}",
2649
+ "wf_version.yml_not_found": "version.yml을 찾을 수 없습니다",
2650
+ "wf_version.commits_since": "{last_tag} 이후 커밋: {n}개",
2651
+ "wf_version.no_changes_synced": "커밋할 변경 사항이 없습니다 (이미 동기화됨)",
2652
+ "wf_version.bump_pushed": "버전 승격 커밋을 push했습니다",
2653
+ "wf_version.commit_failed": "커밋에 실패했습니다",
2654
+ "wf_version.no_develop": "브랜치 {develop_branch}이(가) 없어 역병합할 것이 없습니다",
2655
+ "wf_version.already_contains": "{develop_branch}이(가) 이미 {main_branch}를 포함합니다",
2656
+ "wf_version.backmerged": "안전망 버전 승격 v{new_version}을(를) {develop_branch}에 병합했습니다",
2657
+ "wf_version.push_retry": "push 시도 {attempt} 실패 — 다시 시도합니다",
2658
+ "wf_version.finished": "version-control 워크플로우 종료",
2659
+ "wf_version.sum_skipped": " 건너뜀 (릴리스 병합 / trunk-based): {skip}",
2660
+ "wf_version.sum_previous": " 이전 버전: {current_version}",
2661
+ "wf_version.sum_new": " 새 버전: {new_version}",
2662
+ "wf_version.sum_branch": " 브랜치: {ref_name}",
2663
+ # --- wf_flutter ---
2664
+ "wf_flutter.env_file_created": "✅ {file} 파일 생성 완료",
2665
+ "wf_flutter.dotenv_created": ".env 파일 생성 완료",
2666
+ "wf_flutter.dart_define_prepared": "dart-define 파일 준비 완료",
2667
+ "wf_flutter.google_services_created": "✅ google-services.json 생성 완료",
2668
+ "wf_flutter.google_services_skipped": "ℹ️ GOOGLE_SERVICES_JSON 시크릿이 없어 건너뜁니다",
2669
+ "wf_flutter.flutter_setup_done_ok": "✅ Flutter 설정 완료",
2670
+ "wf_flutter.flutter_setup_done": "Flutter 설정 완료",
2671
+ "wf_flutter.deps_installed_ok": "✅ 의존성 설치 완료",
2672
+ "wf_flutter.deps_installed": "의존성 설치 완료",
2673
+ "wf_flutter.gradle_perm_ok": "✅ Gradle wrapper 권한 설정 완료",
2674
+ "wf_flutter.gradle_perm": "Gradle wrapper 권한 설정 완료",
2675
+ "wf_flutter.java_setup_done_ok": "✅ Java 설정 완료",
2676
+ "wf_flutter.java_setup_done": "Java 설정 완료",
2677
+ "wf_flutter.apk_built_ok": "✅ APK 빌드 완료",
2678
+ "wf_flutter.apk_built": "APK 빌드 완료",
2679
+ "wf_flutter.apk_renamed_ok": "✅ APK 이름 변경 완료: {name}",
2680
+ "wf_flutter.apk_renamed": "APK 이름 변경 완료: {name}",
2681
+ "wf_flutter.repo_checked_out": "저장소 체크아웃 완료",
2682
+ "wf_flutter.keystore_from_debug": "DEBUG_KEYSTORE로 Keystore 생성 완료",
2683
+ "wf_flutter.key_properties_created": "key.properties 생성 완료",
2684
+ "wf_flutter.repo_checked_out_deploy": "배포용 저장소 체크아웃 완료",
2685
+ "wf_flutter.smb_deps_installed": "SMB 및 jq 의존성 설치 완료",
2686
+ "wf_flutter.download_listed": "다운로드한 구조 출력 완료",
2687
+ "wf_flutter.apk_file_found": "APK 파일 확인: {file}",
2688
+ "wf_flutter.smb_uploading": "APK 파일 {name}을(를) SMB로 업로드하는 중...",
2689
+ "wf_flutter.smb_path": "SMB 경로: {path}",
2690
+ "wf_flutter.smb_uploaded": "APK SMB 업로드 완료",
2691
+ "wf_flutter.history_loaded": "{file}을(를) 내려받았거나 새로 초기화했습니다",
2692
+ "wf_flutter.history_updated": "{file}에 새 빌드 정보를 반영했습니다",
2693
+ "wf_flutter.history_uploaded": "갱신된 {file}을(를) SMB로 업로드했습니다",
2694
+ "wf_flutter.secrets_xcconfig_created_ok": "✅ Secrets.xcconfig 생성 완료",
2695
+ "wf_flutter.secrets_xcconfig_empty": "ℹ️ 제공된 시크릿이 없어 빈 Secrets.xcconfig를 생성했습니다",
2696
+ "wf_flutter.secrets_xcconfig_created": "Secrets.xcconfig 생성 완료",
2697
+ "wf_flutter.xcode_platform_check": "=== iPhoneOS.platform 확인 ===",
2698
+ "wf_flutter.xcode_platform_exists": "iPhoneOS.platform 있음",
2699
+ "wf_flutter.xcode_platform_missing": "iPhoneOS.platform 없음",
2700
+ "wf_flutter.xcode_install_pkgs": "=== MobileDevice 패키지 설치 ===",
2701
+ "wf_flutter.xcode_license": "=== Xcode 라이선스 동의 ===",
2702
+ "wf_flutter.xcode_init": "=== Xcode 구성 요소 초기화 ===",
2703
+ "wf_flutter.xcode_download": "=== iOS 플랫폼 다운로드 ===",
2704
+ "wf_flutter.ipa_found": "📦 IPA 위치: {path}",
2705
+ "wf_flutter.release_notes_heading": "📝 릴리스 노트:",
2706
+ "wf_flutter.working_dir": "🔧 작업 디렉터리: {dir}",
2707
+ "wf_flutter.run_number": "🔍 GitHub 실행 번호: {number}",
2708
+ "wf_flutter.ci_analyze_only": " 분석 전용: {value}",
2273
2709
  }
2274
2710
 
2275
2711
  CATALOG = {"en": EN, "ko": KO}