project-auto-wizard 0.15.0 → 0.16.0

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 (65) hide show
  1. package/README.ja.md +1 -1
  2. package/README.ko.md +1 -1
  3. package/README.md +2 -2
  4. package/README.zh-CN.md +1 -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/messages.py +162 -26
  9. package/payload/scripts/version_manager.py +69 -40
  10. package/payload/version.yml.template +6 -2
  11. package/payload/workflows/common/PROJECT-COMMON-AI-PR-SUMMARY.yaml +3 -0
  12. package/payload/workflows/common/PROJECT-COMMON-AUTO-CHANGELOG-CONTROL.yaml +64 -1
  13. package/payload/workflows/common/PROJECT-COMMON-README-VERSION-UPDATE.yaml +61 -12
  14. package/payload/workflows/common/PROJECT-COMMON-RELEASE-PUBLISH.yaml +46 -10
  15. package/payload/workflows/common/PROJECT-COMMON-VERSION-CONTROL.yaml +40 -11
  16. package/payload/workflows/flutter/PROJECT-FLUTTER-ANDROID-FIREBASE-CICD.yaml +24 -8
  17. package/payload/workflows/flutter/PROJECT-FLUTTER-ANDROID-PLAYSTORE-CICD.yaml +29 -10
  18. package/payload/workflows/flutter/PROJECT-FLUTTER-ANDROID-SELFHOSTED-CICD.yaml +57 -23
  19. package/payload/workflows/flutter/PROJECT-FLUTTER-ANDROID-TEST-APK.yaml +155 -72
  20. package/payload/workflows/flutter/PROJECT-FLUTTER-APP-BUILD-TRIGGER.yaml +49 -20
  21. package/payload/workflows/flutter/PROJECT-FLUTTER-CI.yaml +162 -62
  22. package/payload/workflows/flutter/PROJECT-FLUTTER-IOS-TEST-TESTFLIGHT.yaml +184 -87
  23. package/payload/workflows/flutter/PROJECT-FLUTTER-IOS-TESTFLIGHT.yaml +38 -15
  24. package/payload/workflows/go/PROJECT-GO-CI.yaml +14 -5
  25. package/payload/workflows/go/PROJECT-GO-PR-PREVIEW.yaml +375 -120
  26. package/payload/workflows/go/PROJECT-GO-SIMPLE-CICD.yaml +9 -4
  27. package/payload/workflows/python/PROJECT-PYTHON-CI.yaml +12 -4
  28. package/payload/workflows/python/PROJECT-PYTHON-PR-PREVIEW.yaml +375 -120
  29. package/payload/workflows/python/PROJECT-PYTHON-SIMPLE-CICD.yaml +9 -4
  30. package/payload/workflows/react/PROJECT-REACT-CI.yaml +38 -9
  31. package/payload/workflows/react/PROJECT-REACT-CICD.yaml +19 -5
  32. package/payload/workflows/spring/PROJECT-SPRING-CI.yml +71 -35
  33. package/payload/workflows/spring/server-deploy/PROJECT-SPRING-NONSTOP-NGINX-CICD.yaml +9 -6
  34. package/payload/workflows/spring/server-deploy/PROJECT-SPRING-NONSTOP-TRAEFIK-CICD.yaml +7 -4
  35. package/payload/workflows/spring/server-deploy/PROJECT-SPRING-PR-PREVIEW.yaml +425 -144
  36. package/payload/workflows/spring/server-deploy/PROJECT-SPRING-SIMPLE-CICD.yaml +7 -4
  37. package/src/cli/args.js +32 -22
  38. package/src/commands/doctor.js +20 -0
  39. package/src/commands/dry-run.js +9 -1
  40. package/src/commands/full.js +9 -4
  41. package/src/commands/interactive.js +29 -30
  42. package/src/commands/status.js +19 -5
  43. package/src/context.js +4 -2
  44. package/src/core/copy/simple.js +31 -0
  45. package/src/core/copy/workflows.js +2 -2
  46. package/src/core/deploy-style.js +1 -1
  47. package/src/core/detect.js +3 -2
  48. package/src/core/options.js +88 -0
  49. package/src/core/release-options.js +6 -23
  50. package/src/core/types.js +15 -8
  51. package/src/core/version-yml.js +68 -26
  52. package/src/i18n/catalog/en/cli.js +3 -1
  53. package/src/i18n/catalog/en/commands.js +15 -0
  54. package/src/i18n/catalog/en/core2.js +3 -0
  55. package/src/i18n/catalog/en/ui.js +1 -0
  56. package/src/i18n/catalog/ko/cli.js +3 -1
  57. package/src/i18n/catalog/ko/commands.js +15 -0
  58. package/src/i18n/catalog/ko/core2.js +3 -0
  59. package/src/i18n/catalog/ko/ui.js +1 -0
  60. package/src/index.js +7 -3
  61. package/src/ui/env-plan.js +1 -1
  62. package/src/ui/prompts.js +9 -5
  63. package/src/ui/status-cards.js +2 -2
  64. package/payload/workflows/next/PROJECT-NEXT-CI.yaml +0 -241
  65. package/payload/workflows/next/PROJECT-NEXT-CICD.yaml +0 -330
package/README.ja.md CHANGED
@@ -127,7 +127,7 @@ feature PRs ──▶ develop ──▶ release PR (develop → main)
127
127
  |---|---|---|
128
128
  | `spring` | `build.gradle`、`build.gradle.kts`、`pom.xml` | CI、サーバーへのデプロイ(単一サーバー / Nginx または Traefik によるダウンタイムなし)、PR プレビュー |
129
129
  | `flutter` | `pubspec.yaml` | CI、Android(Firebase、Play Store、セルフホスト、テスト用 APK)、iOS TestFlight |
130
- | `react`、`next` | `package.json` の dependencies | CI、CI + CD |
130
+ | `react`(React / Next.js) | `package.json` の `react` または `next` dependency | CI、CI + CD |
131
131
  | `python` | `pyproject.toml`、`setup.py`、`requirements.txt` | CI、PR プレビュー、サーバーへのデプロイ |
132
132
  | `go` | `go.mod` | CI、PR プレビュー、サーバーへのデプロイ |
133
133
  | `node`、`react-native`、`react-native-expo`、`basic` | `package.json` / フォールバック | リリース自動化のみ |
package/README.ko.md CHANGED
@@ -127,7 +127,7 @@ feature PRs ──▶ develop ──▶ release PR (develop → main)
127
127
  |---|---|---|
128
128
  | `spring` | `build.gradle`, `build.gradle.kts`, `pom.xml` | CI, 서버 배포 (단일 서버 / Nginx·Traefik 무중단), PR 프리뷰 |
129
129
  | `flutter` | `pubspec.yaml` | CI, Android (Firebase, Play Store, self-hosted, 테스트 APK), iOS TestFlight |
130
- | `react`, `next` | `package.json` dependencies | CI, CI + CD |
130
+ | `react` (React / Next.js) | `package.json`의 `react` 또는 `next` dependency | CI, CI + CD |
131
131
  | `python` | `pyproject.toml`, `setup.py`, `requirements.txt` | CI, PR 프리뷰, 서버 배포 |
132
132
  | `go` | `go.mod` | CI, PR 프리뷰, 서버 배포 |
133
133
  | `node`, `react-native`, `react-native-expo`, `basic` | `package.json` / fallback | 릴리스 자동화만 |
package/README.md CHANGED
@@ -21,7 +21,7 @@ Everything it installs is plain GitHub Actions in your own repository. No API ke
21
21
  </div>
22
22
 
23
23
  <!-- AUTO-VERSION-SECTION: DO NOT EDIT MANUALLY -->
24
- ## Latest Version : v0.15.0 (2026-09-30)
24
+ ## Latest Version : v0.16.0 (2026-10-01)
25
25
 
26
26
  [Full release history](CHANGELOG.md)
27
27
 
@@ -128,7 +128,7 @@ Skip it if:
128
128
  |---|---|---|
129
129
  | `spring` | `build.gradle`, `build.gradle.kts`, `pom.xml` | CI, server deploy (single server / zero-downtime Nginx or Traefik), PR preview |
130
130
  | `flutter` | `pubspec.yaml` | CI, Android (Firebase, Play Store, self-hosted, test APK), iOS TestFlight |
131
- | `react`, `next` | `package.json` dependencies | CI, CI + CD |
131
+ | `react` (React / Next.js) | `package.json` with a `react` or `next` dependency | CI, CI + CD |
132
132
  | `python` | `pyproject.toml`, `setup.py`, `requirements.txt` | CI, PR preview, server deploy |
133
133
  | `go` | `go.mod` | CI, PR preview, server deploy |
134
134
  | `node`, `react-native`, `react-native-expo`, `basic` | `package.json` / fallback | Release automation only |
package/README.zh-CN.md CHANGED
@@ -127,7 +127,7 @@ feature PRs ──▶ develop ──▶ release PR (develop → main)
127
127
  |---|---|---|
128
128
  | `spring` | `build.gradle`、`build.gradle.kts`、`pom.xml` | CI、服务器部署(单台服务器 / Nginx 或 Traefik 零停机)、PR 预览 |
129
129
  | `flutter` | `pubspec.yaml` | CI、Android(Firebase、Play Store、自托管、测试 APK)、iOS TestFlight |
130
- | `react`、`next` | `package.json` 的 dependencies | CI、CI + CD |
130
+ | `react`(React / Next.js) | `package.json` 中的 `react` 或 `next` dependency | CI、CI + CD |
131
131
  | `python` | `pyproject.toml`、`setup.py`、`requirements.txt` | CI、PR 预览、服务器部署 |
132
132
  | `go` | `go.mod` | CI、PR 预览、服务器部署 |
133
133
  | `node`、`react-native`、`react-native-expo`、`basic` | `package.json` / 兜底 | 仅发布自动化 |
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "project-auto-wizard",
3
- "version": "0.15.0",
3
+ "version": "0.16.0",
4
4
  "description": "One command DevOps: npx wizard that installs GitHub-native Release Automation (optional GitHub Copilot AI summaries) into any project",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -2,7 +2,9 @@
2
2
  "0.10.1": [
3
3
  {
4
4
  "severity": "warning",
5
- "types": ["flutter"],
5
+ "types": [
6
+ "flutter"
7
+ ],
6
8
  "title": "Flutter SELFHOSTED and TEST-APK now run flutter build directly",
7
9
  "message": "SELFHOSTED and TEST-APK run flutter build apk --release directly instead of fastlane build, and the Ruby/fastlane install steps are gone. fastlane is now used only by the three store deploy workflows (PLAYSTORE, IOS-TESTFLIGHT, IOS-TEST-TESTFLIGHT).",
8
10
  "title_ko": "Flutter SELFHOSTED·TEST-APK가 flutter build를 직접 실행",
@@ -10,7 +12,9 @@
10
12
  },
11
13
  {
12
14
  "severity": "warning",
13
- "types": ["flutter"],
15
+ "types": [
16
+ "flutter"
17
+ ],
14
18
  "title": "Flutter env default switched to dart-define",
15
19
  "message": "New installs default to dart-define (--dart-define-from-file). Existing installs keep dotenv (a generated .env) when version.yml has no saved value; to change it, use the wizard 'Modify > environment variable method' or --flutter-env-mode.",
16
20
  "title_ko": "Flutter 환경변수 기본 방식이 dart-define으로 변경",
@@ -18,7 +22,9 @@
18
22
  },
19
23
  {
20
24
  "severity": "warning",
21
- "types": ["flutter"],
25
+ "types": [
26
+ "flutter"
27
+ ],
22
28
  "title": "Flutter workflows now run from FLUTTER_PROJECT_DIR",
23
29
  "message": "FIREBASE, SELFHOSTED, CI, TEST-APK and IOS-TEST-TESTFLIGHT now run from the Flutter root (FLUTTER_PROJECT_DIR), like PLAYSTORE. For a monorepo where Flutter lives in a subfolder, set it with --paths flutter=<path>.",
24
30
  "title_ko": "Flutter 워크플로우가 FLUTTER_PROJECT_DIR 기준으로 동작",
@@ -26,7 +32,13 @@
26
32
  },
27
33
  {
28
34
  "severity": "warning",
29
- "types": ["flutter", "go", "next", "python", "react", "spring"],
35
+ "types": [
36
+ "flutter",
37
+ "go",
38
+ "python",
39
+ "react",
40
+ "spring"
41
+ ],
30
42
  "title": "Register only ci-gate as the monorepo CI required check",
31
43
  "message": "CI workflows (Flutter, Go, Next, Python, React, Spring CI) always run and skip their jobs when nothing changed. To use them as a required check, register only the CI Gate (ci-gate), not the individual jobs.",
32
44
  "title_ko": "모노레포 CI required check는 ci-gate 하나만 등록",
@@ -45,7 +57,9 @@
45
57
  "0.12.1": [
46
58
  {
47
59
  "severity": "warning",
48
- "types": ["spring"],
60
+ "types": [
61
+ "spring"
62
+ ],
49
63
  "title": "Spring nexus and GitHub Packages publish options removed",
50
64
  "message": "PROJECT-SPRING-NEXUS-PUBLISH.yml and PROJECT-SPRING-GITHUB-PACKAGES-PUBLISH.yml are no longer installed, and PROJECT-SPRING-NEXUS-CI.yml became PROJECT-SPRING-CI.yml, which is always installed. On update, untouched old files are deleted and modified ones are moved to .bak. To keep deploying, move the .bak into a workflow you maintain yourself.",
51
65
  "title_ko": "Spring nexus·GitHub Packages publish 옵션 제거",
@@ -58,5 +72,17 @@
58
72
  "title_ko": "Secret 서버 백업 워크플로우(secret_backup 옵션) 제거",
59
73
  "message_ko": "PROJECT-COMMON-SECRET-FILE-UPLOAD.yaml을 더 이상 설치하지 않습니다. 설치해 두었다면 업데이트 때 손대지 않은 파일은 삭제되고 수정한 파일은 .bak으로 옮겨집니다. 계속 쓰려면 .bak을 직접 관리하는 워크플로우로 옮기세요."
60
74
  }
75
+ ],
76
+ "0.15.1": [
77
+ {
78
+ "severity": "warning",
79
+ "types": [
80
+ "react"
81
+ ],
82
+ "title": "The next type is now react; Next.js deploy names changed",
83
+ "message": "Next.js projects are now the react type (next is still accepted as an alias). PROJECT-NEXT-CI and PROJECT-NEXT-CICD are replaced by PROJECT-REACT-CI and PROJECT-REACT-CICD on update (untouched old files are deleted, modified ones move to .bak). The deploy image prefix changes from nextjs-container to front-container and the container from <project>-nextjs-deploy to <project>-front-deploy, so the first deploy pulls a new image; the workflow removes the old nextjs container automatically before starting the new one. Clean up the old image on the server if you no longer need it.",
84
+ "title_ko": "next 타입이 react로 통합되고 Next.js 배포 이름이 바뀜",
85
+ "message_ko": "Next.js 프로젝트는 이제 react 타입입니다(next는 별칭으로 계속 받습니다). 업데이트하면 PROJECT-NEXT-CI·PROJECT-NEXT-CICD가 PROJECT-REACT-CI·PROJECT-REACT-CICD로 교체됩니다(손대지 않은 이전 파일은 삭제, 수정한 파일은 .bak으로 이동). 배포 이미지 접두어가 nextjs-container에서 front-container로, 컨테이너 이름이 <프로젝트>-nextjs-deploy에서 <프로젝트>-front-deploy로 바뀌므로 첫 배포에서 새 이미지를 받으며, 워크플로우가 새 컨테이너를 띄우기 전에 이전 nextjs 컨테이너를 자동으로 지웁니다. 이전 이미지가 필요 없다면 서버에서 직접 정리하세요."
86
+ }
61
87
  ]
62
88
  }
@@ -150,8 +150,6 @@ _workflow_names:
150
150
  SIMPLE-CICD: "Single-server deploy"
151
151
  REACT-CICD: "Frontend deploy"
152
152
  REACT-CI: "Frontend build"
153
- NEXT-CICD: "Frontend deploy"
154
- NEXT-CI: "Frontend build"
155
153
  PYTHON-CI: "Build check"
156
154
  FLUTTER-ANDROID-SELFHOSTED: "Android self-hosted deploy"
157
155
  FLUTTER-ANDROID-PLAYSTORE: "Play Store deploy"
@@ -165,8 +163,6 @@ _workflow_names_ko:
165
163
  SIMPLE-CICD: "단일 서버 배포"
166
164
  REACT-CICD: "프론트 배포"
167
165
  REACT-CI: "프론트 빌드"
168
- NEXT-CICD: "프론트 배포"
169
- NEXT-CI: "프론트 빌드"
170
166
  PYTHON-CI: "빌드 검증"
171
167
  FLUTTER-ANDROID-SELFHOSTED: "안드로이드 자체배포"
172
168
  FLUTTER-ANDROID-PLAYSTORE: "플레이스토어 배포"
@@ -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,6 +1225,10 @@ 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}",
@@ -1239,7 +1260,7 @@ EN = {
1239
1260
  "version_manager.sync_project_version": " project file: {version}",
1240
1261
  "version_manager.sync_mismatch": "Version mismatch detected, syncing to higher version: {version}",
1241
1262
  "version_manager.warn_format_invalid": "WARNING: version format invalid, cannot sync",
1242
- "version_manager.sync_multi": "Multi-type — reconciling all type files to version.yml version: {version}",
1263
+ "version_manager.sync_reconciled": "Version files updated to match version.yml: {version}",
1243
1264
  "version_manager.sync_ok": "Version already in sync: {version}",
1244
1265
  "version_manager.err_invalid_version": "ERROR: invalid version format: {version}",
1245
1266
  "version_manager.err_invalid_version_xyz": "ERROR: invalid version format: {version} (must be x.y.z)",
@@ -1269,6 +1290,7 @@ EN = {
1269
1290
  "wf_common.rebase_ok": "rebase ok, retrying push...",
1270
1291
  "wf_common.rebase_failed": "rebase failed, manual conflict resolution required",
1271
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",
1272
1294
  # --- wf_aisum ---
1273
1295
  "wf_aisum.expected_version": "expected next version: {version} (current: {current_version}, mode: {mode}, bump: {bump})",
1274
1296
  "wf_aisum.comment_update_failed": "comment update failed — continuing (this workflow never blocks the PR)",
@@ -1291,6 +1313,9 @@ EN = {
1291
1313
  "wf_changelog.pr_already_merged": "PR #{pr_number} is already merged",
1292
1314
  "wf_changelog.automerge_enabled": "automerge enabled: {subject}",
1293
1315
  "wf_changelog.automerge_unavailable": "automerge unavailable — merged directly: {subject}",
1316
+ "wf_changelog.automerge_off": "release_automerge is off — PR renamed to \"{subject}\"; merge it yourself",
1317
+ "wf_changelog.automerge_rename_failed": "Could not update PR #{pr_number} (title or guidance comment); the release still needs \"chore(release):\" in the merge commit message",
1318
+ "wf_changelog.automerge_off_comment": "**Automatic merge is off** (`release_automerge: false` in `version.yml`). Merge this PR yourself when you are ready to release, using **Create a merge commit**. Do not use *Squash and merge* or *Rebase and merge*: the release gate reads `chore(release):` from the resulting commit message, and squashing or rebasing also rewrites the history that the next release notes are built from.",
1294
1319
  "wf_changelog.merge_retry": "merge attempt {attempt}/{max_attempts} failed — retrying in {wait}s",
1295
1320
  "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",
1296
1321
  # --- wf_readme ---
@@ -1319,6 +1344,9 @@ EN = {
1319
1344
  "wf_readme.line_updated": "version line updated: {version_text}",
1320
1345
  "wf_readme.no_changes": "no changes in README.md",
1321
1346
  "wf_readme.pushed": "README.md version update pushed",
1347
+ "wf_readme.trunk_skip": "trunk-based push: RELEASE-PUBLISH updates the README and dispatches this workflow, skipping",
1348
+ "wf_readme.conflict_skip_same": "remote README.md already shows v{version}, skipping",
1349
+ "wf_readme.conflict_skip_stale": "remote is already at v{remote_version} (this run had v{version}), skipping the stale README update",
1322
1350
  "wf_readme.err_no_colon": "header extraction failed - no colon (:) found",
1323
1351
  "wf_readme.err_sed": "sed command failed - {error}",
1324
1352
  "wf_readme.err_sed_unknown": "unknown sed error",
@@ -1365,6 +1393,52 @@ EN = {
1365
1393
  "wf_version.sum_previous": " previous version: {current_version}",
1366
1394
  "wf_version.sum_new": " new version: {new_version}",
1367
1395
  "wf_version.sum_branch": " branch: {ref_name}",
1396
+ # --- wf_flutter ---
1397
+ "wf_flutter.env_file_created": "✅ {file} file created",
1398
+ "wf_flutter.dotenv_created": ".env file created",
1399
+ "wf_flutter.dart_define_prepared": "dart-define file prepared",
1400
+ "wf_flutter.google_services_created": "✅ google-services.json created",
1401
+ "wf_flutter.google_services_skipped": "ℹ️ GOOGLE_SERVICES_JSON secret not provided, skipping",
1402
+ "wf_flutter.flutter_setup_done_ok": "✅ Flutter setup completed",
1403
+ "wf_flutter.flutter_setup_done": "Flutter setup completed",
1404
+ "wf_flutter.deps_installed_ok": "✅ Dependencies installed",
1405
+ "wf_flutter.deps_installed": "Dependencies installed",
1406
+ "wf_flutter.gradle_perm_ok": "✅ Gradle wrapper permissions set",
1407
+ "wf_flutter.gradle_perm": "Gradle wrapper permissions set",
1408
+ "wf_flutter.java_setup_done_ok": "✅ Java setup completed",
1409
+ "wf_flutter.java_setup_done": "Java setup completed",
1410
+ "wf_flutter.apk_built_ok": "✅ APK built",
1411
+ "wf_flutter.apk_built": "APK built",
1412
+ "wf_flutter.apk_renamed_ok": "✅ APK renamed to {name}",
1413
+ "wf_flutter.apk_renamed": "APK renamed to {name}",
1414
+ "wf_flutter.repo_checked_out": "Repository checked out",
1415
+ "wf_flutter.keystore_from_debug": "Keystore created from DEBUG_KEYSTORE",
1416
+ "wf_flutter.key_properties_created": "key.properties created",
1417
+ "wf_flutter.repo_checked_out_deploy": "Repository checked out for deploy",
1418
+ "wf_flutter.smb_deps_installed": "SMB and jq dependencies installed",
1419
+ "wf_flutter.download_listed": "Downloaded structure listed",
1420
+ "wf_flutter.apk_file_found": "APK file found: {file}",
1421
+ "wf_flutter.smb_uploading": "Uploading APK file {name} to SMB...",
1422
+ "wf_flutter.smb_path": "SMB Path: {path}",
1423
+ "wf_flutter.smb_uploaded": "APK uploaded to SMB",
1424
+ "wf_flutter.history_loaded": "Downloaded or initialized {file}",
1425
+ "wf_flutter.history_updated": "Updated {file} with new build info",
1426
+ "wf_flutter.history_uploaded": "Updated {file} uploaded to SMB",
1427
+ "wf_flutter.secrets_xcconfig_created_ok": "✅ Secrets.xcconfig created",
1428
+ "wf_flutter.secrets_xcconfig_empty": "ℹ️ Empty Secrets.xcconfig created (no secrets provided)",
1429
+ "wf_flutter.secrets_xcconfig_created": "Secrets.xcconfig created",
1430
+ "wf_flutter.xcode_platform_check": "=== iPhoneOS.platform check ===",
1431
+ "wf_flutter.xcode_platform_exists": "iPhoneOS.platform EXISTS",
1432
+ "wf_flutter.xcode_platform_missing": "iPhoneOS.platform NOT FOUND",
1433
+ "wf_flutter.xcode_install_pkgs": "=== Installing MobileDevice packages ===",
1434
+ "wf_flutter.xcode_license": "=== Accepting Xcode license ===",
1435
+ "wf_flutter.xcode_init": "=== Initializing Xcode components ===",
1436
+ "wf_flutter.xcode_download": "=== Downloading iOS platform ===",
1437
+ "wf_flutter.ipa_found": "📦 Found IPA at: {path}",
1438
+ "wf_flutter.release_notes_heading": "📝 Release Notes:",
1439
+ "wf_flutter.working_dir": "🔧 Working directory: {dir}",
1440
+ "wf_flutter.run_number": "🔍 GitHub Run Number: {number}",
1441
+ "wf_flutter.ci_analyze_only": " Analyze Only: {value}",
1368
1442
  }
1369
1443
 
1370
1444
  KO = {
@@ -1623,7 +1697,6 @@ KO = {
1623
1697
  "cibuild.node_deps_done": "✅ 의존성 설치 완료",
1624
1698
  "cibuild.node_no_test_script": "::notice::package.json에 test 스크립트가 없어 테스트를 건너뜁니다",
1625
1699
  "cibuild.node_test_run": "🧪 npm test 실행: {script}",
1626
- "cibuild.node_build_start_next": "🔨 Next.js 빌드 시작...",
1627
1700
  "cibuild.node_build_start": "🔨 빌드 시작...",
1628
1701
  "cibuild.node_build_project": "프로젝트: {project}",
1629
1702
  "cibuild.node_build_node": "Node.js: {node}",
@@ -1633,8 +1706,6 @@ KO = {
1633
1706
  "cibuild.node_build_next_dir": " - .next/ 폴더 생성됨",
1634
1707
  "cibuild.node_errlog_title": "❌ 빌드 실패 - 에러 로그",
1635
1708
  "cibuild.node_errlog_missing": "에러 로그 파일을 찾을 수 없습니다.",
1636
- "cibuild.node_result_next_ok": "🎉 Next.js 빌드 완료!",
1637
- "cibuild.node_result_next_fail": "❌ Next.js 빌드 실패",
1638
1709
  "cibuild.node_result_ok": "🎉 빌드 워크플로우 완료!",
1639
1710
  "cibuild.node_result_fail": "❌ 빌드 워크플로우 실패",
1640
1711
  "cibuild.node_result_title": "📊 빌드 결과:",
@@ -1643,15 +1714,18 @@ KO = {
1643
1714
  "cibuild.node_result_status": " 🆙 빌드 상태: {status}",
1644
1715
  "cibuild.node_result_branch": " 🌿 브랜치: {branch}",
1645
1716
  "cibuild.node_result_commit": " 📝 커밋: {sha}",
1646
- "cibuild.node_result_time": " 🕐 시간: {time}",
1717
+ "cibuild.node_result_time": " ⏰ 검증 시간: {time}",
1647
1718
  "cibuild.node_all_ok": "✅ 모든 단계가 성공적으로 완료되었습니다.",
1648
1719
  "cibuild.node_error_occurred": "❌ 빌드 중 오류가 발생했습니다.",
1649
1720
  "cibuild.node_log_hint": "💡 Actions 탭에서 'build-log' 아티팩트를 다운로드하여 전체 로그를 확인하세요.",
1721
+ "cibuild.node_result_status_not_run": " 🆙 빌드 상태: 실행 안 됨 (이전 단계 실패)",
1722
+ "cibuild.node_build_not_run": "❌ 이전 단계(예: 테스트)가 실패하여 빌드가 실행되지 않았습니다.",
1723
+ "cibuild.node_build_not_run_hint": "💡 위에서 실패한 단계의 로그를 확인하세요. 이번 실행에는 'build-log' 아티팩트가 없습니다.",
1650
1724
  "cibuild.gate_results": "needs 결과: {results}",
1651
1725
  "cibuild.gate_failed": "실패하거나 취소된 job이 있습니다.",
1652
1726
  # --- cicd ---
1653
1727
  "cicd.precheck_secret_title": "필수 Secret 누락",
1654
- "cicd.precheck_secret_body": "등록되지 않은 GitHub Secret:{missing} — Settings → Secrets and variables → Actions에서 등록하세요",
1728
+ "cicd.precheck_secret_body": "필수 GitHub Secret이 비어 있습니다:{missing} — Settings → Secrets and variables → Actions에서 등록하세요",
1655
1729
  "cicd.precheck_dockerfile_title": "Dockerfile 없음",
1656
1730
  "cicd.precheck_dockerfile_body": "{path} 파일이 없습니다. 이 워크플로우는 Docker 이미지로 배포하므로 Dockerfile이 필요합니다 (서버 배포를 하지 않는다면 이 워크플로우 파일을 삭제하세요)",
1657
1731
  "cicd.precheck_ok": "✅ 사전 점검 통과: 필수 Secret과 Dockerfile이 모두 있습니다",
@@ -1678,7 +1752,6 @@ KO = {
1678
1752
  "cicd.config_port": " - 포트: {port}",
1679
1753
  "cicd.config_image": " - Docker 이미지: {image}",
1680
1754
  "cicd.pull_image": "⬇️ Docker 이미지 풀: {image}",
1681
- "cicd.pull_image_short": "⬇️ Docker 이미지 풀...",
1682
1755
  "cicd.container_check": "🧹 컨테이너 {container} 존재 여부 확인 중...",
1683
1756
  "cicd.container_exists": "⚠️ 컨테이너 {container} 이(가) 존재합니다. 중지 및 삭제 중...",
1684
1757
  "cicd.container_removed": "✅ 컨테이너 {container} 이(가) 삭제되었습니다.",
@@ -1727,7 +1800,7 @@ KO = {
1727
1800
  "fastlane.play_deploy": "Play 배포: DEPLOY_MODE={deploy_mode} → track={track}, release_status={release_status}",
1728
1801
  # --- flutter_a ---
1729
1802
  "flutter_a.precheck_missing_title": "필수 Secret 누락",
1730
- "flutter_a.precheck_missing_body": "등록되지 않은 GitHub Secret:{missing} — Settings → Secrets and variables → Actions에서 등록하세요",
1803
+ "flutter_a.precheck_missing_body": "필수 GitHub Secret이 비어 있습니다:{missing} — Settings → Secrets and variables → Actions에서 등록하세요",
1731
1804
  "flutter_a.precheck_passed": "✅ 사전 점검 통과: 필수 Secret이 모두 있습니다",
1732
1805
  "flutter_a.debug_keystore_empty": "DEBUG_KEYSTORE Secret이 비어 있어 러너 기본 debug 키로 서명합니다 (빌드마다 서명이 달라집니다)",
1733
1806
  "flutter_a.debug_keystore_created": "Debug Keystore created (DEBUG_KEYSTORE로 서명)",
@@ -2093,6 +2166,9 @@ KO = {
2093
2166
  "wf_changelog.merge_confirmed": "PR #{pr} 병합 확인 (경과 {elapsed}s)",
2094
2167
  "wf_changelog.merge_timeout": "PR #{pr} 병합을 {max}s 내에 확인하지 못했습니다 — RELEASE-PUBLISH 자동 트리거를 건너뜁니다. WORKFLOW_PAT이 등록되어 있다면 기존 경로로 정상 진행되며, 없다면 필요 시 RELEASE-PUBLISH를 수동으로 workflow_dispatch 하세요.",
2095
2168
  "wf_changelog.release_publish_triggered": "RELEASE-PUBLISH workflow_dispatch 트리거 요청 완료 (WORKFLOW_PAT 없이도 동작)",
2169
+ # --- lang ---
2170
+ "lang.fallback": "지원하지 않는 language 값 '{value}' - '{lang_code}'(으)로 대체합니다 (지원: {supported})",
2171
+
2096
2172
  # --- wf_preview ---
2097
2173
  "wf_preview.chk_deleted_3": "3. 브랜치가 삭제되지 않았는지 확인하세요",
2098
2174
  "wf_preview.chk_helper_exists": "1. Issue Helper 댓글이 존재하는지 확인하세요",
@@ -2174,8 +2250,10 @@ KO = {
2174
2250
  "wf_preview.precheck_dockerfile_body": "{path} 파일이 없습니다. 이 워크플로우는 Docker 이미지로 배포하므로 Dockerfile이 필요합니다 (서버 배포를 하지 않는다면 이 워크플로우 파일을 삭제하세요)",
2175
2251
  "wf_preview.precheck_dockerfile_title": "Dockerfile 없음",
2176
2252
  "wf_preview.precheck_ok": "✅ 사전 점검 통과: 필수 Secret과 Dockerfile이 모두 있습니다",
2177
- "wf_preview.precheck_secret_body": "등록되지 않은 GitHub Secret:{missing} — Settings → Secrets and variables → Actions에서 등록하세요",
2253
+ "wf_preview.precheck_secret_body": "필수 GitHub Secret이 비어 있습니다:{missing} — Settings → Secrets and variables → Actions에서 등록하세요",
2178
2254
  "wf_preview.precheck_secret_title": "필수 Secret 누락",
2255
+ "wf_preview.precheck_skip_body": "미리보기 배포용 Secret이 등록되지 않았습니다:{missing} — 배포된 미리보기가 없으므로 삭제할 것이 없습니다",
2256
+ "wf_preview.precheck_skip_title": "미리보기 정리 건너뜀",
2179
2257
  "wf_preview.r_container_absent": "❌ 컨테이너 없음",
2180
2258
  "wf_preview.r_container_confirmed": "✅ 컨테이너 실행 확인됨",
2181
2259
  "wf_preview.r_container_exited": "❌ 컨테이너 비정상 종료!",
@@ -2265,6 +2343,7 @@ KO = {
2265
2343
  "wf_preview.title_pr_deployed": "## ✅ PR Preview 배포 완료!",
2266
2344
  "wf_preview.title_pr_failed": "## ❌ PR Preview 배포 실패!",
2267
2345
  "wf_preview.title_running": "## ✅ Preview 환경 실행 중",
2346
+ "wf_preview.r_preview_url": "🌐 미리보기 URL: {url}",
2268
2347
  # --- wf_readme ---
2269
2348
  "wf_readme.hint_first_example": "## 최신 버전 : v1.0.0 (2025-08-15)",
2270
2349
  "wf_readme.default_heading": "최신 버전",
@@ -2287,6 +2366,7 @@ KO = {
2287
2366
  # --- wf_spring_ci ---
2288
2367
  "wf_spring_ci.status_ok": "✅ 성공",
2289
2368
  "wf_spring_ci.status_fail": "❌ 실패",
2369
+ "wf_spring_ci.status_not_run": "⏸️ 실행 안 됨 (이전 단계 실패)",
2290
2370
  "wf_spring_ci.err_compile_header": "## 🚨 컴파일 에러",
2291
2371
  "wf_spring_ci.err_compile_missing": "에러 로그를 찾을 수 없습니다.",
2292
2372
  "wf_spring_ci.err_test_header": "## 🧪 테스트 실패",
@@ -2307,7 +2387,6 @@ KO = {
2307
2387
  "wf_spring_ci.fix_error": "- 에러 메시지를 참고하여 코드를 수정해주세요",
2308
2388
  "wf_spring_ci.fix_test": "- 테스트가 실패한 경우 `./gradlew test` 명령어로 테스트를 실행해보세요",
2309
2389
  "wf_spring_ci.footer": "*🤖 GitHub Actions에 의해 자동 생성됨 - {time}*",
2310
- "wf_spring_ci.date_locale": "ko-KR",
2311
2390
  "wf_spring_ci.check_summary_success": "빌드 검증이 성공했습니다.",
2312
2391
  "wf_spring_ci.check_summary_failure": "빌드 검증이 실패했습니다.",
2313
2392
  "wf_spring_ci.check_compile": "컴파일: {status}",
@@ -2419,8 +2498,12 @@ KO = {
2419
2498
  "wf_spring_deploy.traefik_hc_timeout": "❌ 헬스체크 타임아웃 ({sec}초)",
2420
2499
  "wf_spring_deploy.traefik_logs_header": "🔍 {name} 최근 200줄 로그:",
2421
2500
  "wf_spring_deploy.traefik_done": "✅ 무중단 배포 완료. active={name}",
2501
+ "wf_spring_deploy.traefik_active": "🎨 활성={active} → 신규={new}, 이전={old}",
2502
+ "wf_spring_deploy.nginx_colors": "🎨 Blue={blue} | Green={green}",
2503
+ "wf_spring_deploy.nginx_conf_path": "🔧 Nginx 설정 파일: {path}",
2504
+ "wf_spring_deploy.nginx_reload": "🔄 nginx reload 실행",
2422
2505
  # --- wf_version ---
2423
- "wf_version.release_publish_triggered": "RELEASE-PUBLISH workflow_dispatch 트리거 요청 완료 (WORKFLOW_PAT 없이도 동작, 이슈 #61 드리프트 자동 복구)",
2506
+ "wf_version.release_publish_triggered": "RELEASE-PUBLISH workflow_dispatch 트리거 요청 완료 (WORKFLOW_PAT 없이도 동작, 버전 드리프트 자동 복구)",
2424
2507
  "wf_version.backmerge_conflict": "{prod}을 {dev}에 자동 병합하지 못했습니다 (충돌). 다음 릴리스 PR 전에 직접 병합하세요: {manual}",
2425
2508
  "wf_version.backmerge_push_failed": "{dev}에 push하지 못했습니다 (브랜치 보호 등). 다음 릴리스 PR 전에 직접 병합하세요: {manual}",
2426
2509
  # --- version_manager ---
@@ -2450,7 +2533,7 @@ KO = {
2450
2533
  "version_manager.sync_project_version": " 프로젝트 파일: {version}",
2451
2534
  "version_manager.sync_mismatch": "버전 불일치를 감지해 더 높은 버전으로 맞춥니다: {version}",
2452
2535
  "version_manager.warn_format_invalid": "경고: 버전 형식이 올바르지 않아 동기화할 수 없습니다",
2453
- "version_manager.sync_multi": "멀티 타입 — 모든 타입 파일을 version.yml 버전({version})으로 맞춥니다",
2536
+ "version_manager.sync_reconciled": "version.yml 버전({version})에 맞게 버전 파일을 수정했습니다",
2454
2537
  "version_manager.sync_ok": "이미 버전이 일치합니다: {version}",
2455
2538
  "version_manager.err_invalid_version": "오류: 올바르지 않은 버전 형식: {version}",
2456
2539
  "version_manager.err_invalid_version_xyz": "오류: 올바르지 않은 버전 형식: {version} (x.y.z 형식이어야 합니다)",
@@ -2480,6 +2563,7 @@ KO = {
2480
2563
  "wf_common.rebase_ok": "rebase 성공, push를 다시 시도합니다...",
2481
2564
  "wf_common.rebase_failed": "rebase 실패, 충돌을 직접 해결해야 합니다",
2482
2565
  "wf_common.push_gave_up": "push가 {max_retries}회 시도 후에도 실패했습니다",
2566
+ "wf_common.readme_conflict_resolved": "동시에 수정된 README.md 충돌을 원격 내용을 유지하고 버전 줄을 다시 반영해 해결했습니다",
2483
2567
  # --- wf_aisum ---
2484
2568
  "wf_aisum.expected_version": "예상 다음 버전: {version} (현재: {current_version}, 모드: {mode}, 승격: {bump})",
2485
2569
  "wf_aisum.comment_update_failed": "댓글 수정 실패 — 계속 진행합니다 (이 워크플로우는 PR을 막지 않습니다)",
@@ -2502,6 +2586,9 @@ KO = {
2502
2586
  "wf_changelog.pr_already_merged": "PR #{pr_number}은(는) 이미 병합되었습니다",
2503
2587
  "wf_changelog.automerge_enabled": "automerge 활성화: {subject}",
2504
2588
  "wf_changelog.automerge_unavailable": "automerge를 쓸 수 없어 직접 병합했습니다: {subject}",
2589
+ "wf_changelog.automerge_off": "release_automerge가 꺼져 있어 PR 제목을 \"{subject}\"로 바꿨습니다. 직접 머지하세요",
2590
+ "wf_changelog.automerge_rename_failed": "PR #{pr_number}의 제목 또는 안내 댓글을 갱신하지 못했습니다. 릴리스가 되려면 머지 커밋 메시지에 \"chore(release):\"가 있어야 합니다",
2591
+ "wf_changelog.automerge_off_comment": "**자동 머지가 꺼져 있습니다** (`version.yml`의 `release_automerge: false`). 릴리스할 준비가 되면 **Create a merge commit**으로 직접 머지하세요. *Squash and merge*와 *Rebase and merge*는 쓰지 마세요. 릴리스 게이트가 결과 커밋 메시지의 `chore(release):`를 읽고, squash나 rebase는 다음 릴리스 노트가 기대는 커밋 이력까지 바꿉니다.",
2505
2592
  "wf_changelog.merge_retry": "병합 시도 {attempt}/{max_attempts} 실패 — {wait}초 후 다시 시도합니다",
2506
2593
  "wf_changelog.merge_gave_up": "PR 병합이 {max_attempts}회 시도 후에도 실패했습니다 (allow_merge_commit={allow_merge_commit}) — 브랜치 보호 규칙, 필수 체크, 토큰 권한을 확인하세요",
2507
2594
  # --- wf_readme ---
@@ -2530,6 +2617,9 @@ KO = {
2530
2617
  "wf_readme.line_updated": "버전 줄을 수정했습니다: {version_text}",
2531
2618
  "wf_readme.no_changes": "README.md에 변경 사항이 없습니다",
2532
2619
  "wf_readme.pushed": "README.md 버전 수정을 push했습니다",
2620
+ "wf_readme.trunk_skip": "trunk-based push: RELEASE-PUBLISH가 README를 갱신하고 이 워크플로우를 호출하므로 건너뜁니다",
2621
+ "wf_readme.conflict_skip_same": "원격 README.md가 이미 v{version}이라 건너뜁니다",
2622
+ "wf_readme.conflict_skip_stale": "원격이 이미 v{remote_version}입니다 (이 실행은 v{version}), 오래된 README 갱신을 건너뜁니다",
2533
2623
  "wf_readme.err_no_colon": "머리말 추출 실패 - 콜론(:)을 찾을 수 없습니다",
2534
2624
  "wf_readme.err_sed": "sed 명령 실패 - {error}",
2535
2625
  "wf_readme.err_sed_unknown": "알 수 없는 sed 오류",
@@ -2576,6 +2666,52 @@ KO = {
2576
2666
  "wf_version.sum_previous": " 이전 버전: {current_version}",
2577
2667
  "wf_version.sum_new": " 새 버전: {new_version}",
2578
2668
  "wf_version.sum_branch": " 브랜치: {ref_name}",
2669
+ # --- wf_flutter ---
2670
+ "wf_flutter.env_file_created": "✅ {file} 파일 생성 완료",
2671
+ "wf_flutter.dotenv_created": ".env 파일 생성 완료",
2672
+ "wf_flutter.dart_define_prepared": "dart-define 파일 준비 완료",
2673
+ "wf_flutter.google_services_created": "✅ google-services.json 생성 완료",
2674
+ "wf_flutter.google_services_skipped": "ℹ️ GOOGLE_SERVICES_JSON 시크릿이 없어 건너뜁니다",
2675
+ "wf_flutter.flutter_setup_done_ok": "✅ Flutter 설정 완료",
2676
+ "wf_flutter.flutter_setup_done": "Flutter 설정 완료",
2677
+ "wf_flutter.deps_installed_ok": "✅ 의존성 설치 완료",
2678
+ "wf_flutter.deps_installed": "의존성 설치 완료",
2679
+ "wf_flutter.gradle_perm_ok": "✅ Gradle wrapper 권한 설정 완료",
2680
+ "wf_flutter.gradle_perm": "Gradle wrapper 권한 설정 완료",
2681
+ "wf_flutter.java_setup_done_ok": "✅ Java 설정 완료",
2682
+ "wf_flutter.java_setup_done": "Java 설정 완료",
2683
+ "wf_flutter.apk_built_ok": "✅ APK 빌드 완료",
2684
+ "wf_flutter.apk_built": "APK 빌드 완료",
2685
+ "wf_flutter.apk_renamed_ok": "✅ APK 이름 변경 완료: {name}",
2686
+ "wf_flutter.apk_renamed": "APK 이름 변경 완료: {name}",
2687
+ "wf_flutter.repo_checked_out": "저장소 체크아웃 완료",
2688
+ "wf_flutter.keystore_from_debug": "DEBUG_KEYSTORE로 Keystore 생성 완료",
2689
+ "wf_flutter.key_properties_created": "key.properties 생성 완료",
2690
+ "wf_flutter.repo_checked_out_deploy": "배포용 저장소 체크아웃 완료",
2691
+ "wf_flutter.smb_deps_installed": "SMB 및 jq 의존성 설치 완료",
2692
+ "wf_flutter.download_listed": "다운로드한 구조 출력 완료",
2693
+ "wf_flutter.apk_file_found": "APK 파일 확인: {file}",
2694
+ "wf_flutter.smb_uploading": "APK 파일 {name}을(를) SMB로 업로드하는 중...",
2695
+ "wf_flutter.smb_path": "SMB 경로: {path}",
2696
+ "wf_flutter.smb_uploaded": "APK SMB 업로드 완료",
2697
+ "wf_flutter.history_loaded": "{file}을(를) 내려받았거나 새로 초기화했습니다",
2698
+ "wf_flutter.history_updated": "{file}에 새 빌드 정보를 반영했습니다",
2699
+ "wf_flutter.history_uploaded": "갱신된 {file}을(를) SMB로 업로드했습니다",
2700
+ "wf_flutter.secrets_xcconfig_created_ok": "✅ Secrets.xcconfig 생성 완료",
2701
+ "wf_flutter.secrets_xcconfig_empty": "ℹ️ 제공된 시크릿이 없어 빈 Secrets.xcconfig를 생성했습니다",
2702
+ "wf_flutter.secrets_xcconfig_created": "Secrets.xcconfig 생성 완료",
2703
+ "wf_flutter.xcode_platform_check": "=== iPhoneOS.platform 확인 ===",
2704
+ "wf_flutter.xcode_platform_exists": "iPhoneOS.platform 있음",
2705
+ "wf_flutter.xcode_platform_missing": "iPhoneOS.platform 없음",
2706
+ "wf_flutter.xcode_install_pkgs": "=== MobileDevice 패키지 설치 ===",
2707
+ "wf_flutter.xcode_license": "=== Xcode 라이선스 동의 ===",
2708
+ "wf_flutter.xcode_init": "=== Xcode 구성 요소 초기화 ===",
2709
+ "wf_flutter.xcode_download": "=== iOS 플랫폼 다운로드 ===",
2710
+ "wf_flutter.ipa_found": "📦 IPA 위치: {path}",
2711
+ "wf_flutter.release_notes_heading": "📝 릴리스 노트:",
2712
+ "wf_flutter.working_dir": "🔧 작업 디렉터리: {dir}",
2713
+ "wf_flutter.run_number": "🔍 GitHub 실행 번호: {number}",
2714
+ "wf_flutter.ci_analyze_only": " 분석 전용: {value}",
2579
2715
  }
2580
2716
 
2581
2717
  CATALOG = {"en": EN, "ko": KO}