project-auto-wizard 0.13.3 → 0.14.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 (112) hide show
  1. package/README.md +1 -1
  2. package/bin/project-auto-wizard.js +18 -4
  3. package/package.json +2 -2
  4. package/payload/config/breaking-changes.json +28 -14
  5. package/payload/config/wizard-prompts.yml +102 -46
  6. package/payload/flutter-app/android/fastlane/Fastfile.playstore +44 -32
  7. package/payload/flutter-app/ios/ExportOptions.plist +8 -8
  8. package/payload/flutter-app/ios/fastlane/Fastfile +57 -43
  9. package/payload/scripts/changelog_manager.py +296 -257
  10. package/payload/scripts/issue_helper.py +54 -50
  11. package/payload/scripts/messages.py +2279 -0
  12. package/payload/scripts/truncate_release_notes.py +7 -6
  13. package/payload/scripts/version_manager.py +64 -61
  14. package/payload/version.yml.template +2 -1
  15. package/payload/workflows/common/PROJECT-COMMON-AI-PR-SUMMARY.yaml +17 -12
  16. package/payload/workflows/common/PROJECT-COMMON-AUTO-CHANGELOG-CONTROL.yaml +59 -34
  17. package/payload/workflows/common/PROJECT-COMMON-ISSUE-HELPER.yaml +17 -15
  18. package/payload/workflows/common/PROJECT-COMMON-README-VERSION-UPDATE.yaml +17 -10
  19. package/payload/workflows/common/PROJECT-COMMON-RELEASE-PUBLISH.yaml +54 -44
  20. package/payload/workflows/common/PROJECT-COMMON-VERSION-CONTROL.yaml +24 -17
  21. package/payload/workflows/flutter/PROJECT-FLUTTER-ANDROID-FIREBASE-CICD.yaml +194 -184
  22. package/payload/workflows/flutter/PROJECT-FLUTTER-ANDROID-PLAYSTORE-CICD.yaml +226 -213
  23. package/payload/workflows/flutter/PROJECT-FLUTTER-ANDROID-SELFHOSTED-CICD.yaml +46 -42
  24. package/payload/workflows/flutter/PROJECT-FLUTTER-ANDROID-TEST-APK.yaml +334 -241
  25. package/payload/workflows/flutter/PROJECT-FLUTTER-APP-BUILD-TRIGGER.yaml +152 -128
  26. package/payload/workflows/flutter/PROJECT-FLUTTER-CI.yaml +246 -188
  27. package/payload/workflows/flutter/PROJECT-FLUTTER-IOS-TEST-TESTFLIGHT.yaml +353 -238
  28. package/payload/workflows/flutter/PROJECT-FLUTTER-IOS-TESTFLIGHT.yaml +96 -85
  29. package/payload/workflows/go/PROJECT-GO-CI.yaml +47 -36
  30. package/payload/workflows/go/PROJECT-GO-PR-PREVIEW.yaml +945 -508
  31. package/payload/workflows/go/PROJECT-GO-SIMPLE-CICD.yaml +155 -133
  32. package/payload/workflows/next/PROJECT-NEXT-CI.yaml +76 -60
  33. package/payload/workflows/next/PROJECT-NEXT-CICD.yaml +97 -77
  34. package/payload/workflows/python/PROJECT-PYTHON-CI.yaml +62 -47
  35. package/payload/workflows/python/PROJECT-PYTHON-PR-PREVIEW.yaml +942 -505
  36. package/payload/workflows/python/PROJECT-PYTHON-SIMPLE-CICD.yaml +148 -126
  37. package/payload/workflows/react/PROJECT-REACT-CI.yaml +86 -70
  38. package/payload/workflows/react/PROJECT-REACT-CICD.yaml +112 -92
  39. package/payload/workflows/spring/PROJECT-SPRING-CI.yml +112 -82
  40. package/payload/workflows/spring/server-deploy/PROJECT-SPRING-NONSTOP-NGINX-CICD.yaml +180 -150
  41. package/payload/workflows/spring/server-deploy/PROJECT-SPRING-NONSTOP-TRAEFIK-CICD.yaml +161 -131
  42. package/payload/workflows/spring/server-deploy/PROJECT-SPRING-PR-PREVIEW.yaml +970 -549
  43. package/payload/workflows/spring/server-deploy/PROJECT-SPRING-SIMPLE-CICD.yaml +193 -162
  44. package/src/cli/args.js +98 -52
  45. package/src/cli/help.js +8 -41
  46. package/src/commands/doctor.js +85 -89
  47. package/src/commands/dry-run.js +63 -43
  48. package/src/commands/full.js +79 -77
  49. package/src/commands/install-settings.js +16 -15
  50. package/src/commands/interactive-flutter.js +20 -19
  51. package/src/commands/interactive.js +135 -132
  52. package/src/commands/purge.js +47 -42
  53. package/src/commands/status.js +36 -36
  54. package/src/commands/uninstall.js +43 -41
  55. package/src/context.js +12 -11
  56. package/src/core/assets.js +12 -11
  57. package/src/core/baseline.js +27 -27
  58. package/src/core/branches.js +29 -27
  59. package/src/core/branding.js +7 -6
  60. package/src/core/breaking-check.js +22 -21
  61. package/src/core/breaking.js +15 -8
  62. package/src/core/copy/app-files.js +5 -4
  63. package/src/core/copy/flutter-app.js +8 -8
  64. package/src/core/copy/gitignore.js +58 -50
  65. package/src/core/copy/readme.js +45 -35
  66. package/src/core/copy/simple.js +16 -15
  67. package/src/core/copy/workflows.js +131 -124
  68. package/src/core/deploy-style.js +51 -48
  69. package/src/core/detect-fs.js +57 -57
  70. package/src/core/detect.js +67 -65
  71. package/src/core/errors.js +2 -2
  72. package/src/core/flutter-doctor.js +17 -16
  73. package/src/core/flutter-hooks.js +33 -32
  74. package/src/core/flutter-options.js +34 -33
  75. package/src/core/fsutil.js +12 -12
  76. package/src/core/installed-stores.js +4 -4
  77. package/src/core/logger.js +42 -40
  78. package/src/core/paths-resolve.js +88 -86
  79. package/src/core/paths.js +10 -10
  80. package/src/core/release-options.js +8 -8
  81. package/src/core/removal-exec.js +14 -13
  82. package/src/core/removal-plan.js +37 -37
  83. package/src/core/types.js +47 -47
  84. package/src/core/verify.js +44 -38
  85. package/src/core/version-yml.js +76 -68
  86. package/src/core/wizard-env.js +46 -46
  87. package/src/core/wizard-labels.js +63 -41
  88. package/src/i18n/catalog/en/cli.js +50 -0
  89. package/src/i18n/catalog/en/commands.js +187 -0
  90. package/src/i18n/catalog/en/copy.js +19 -0
  91. package/src/i18n/catalog/en/core.js +74 -0
  92. package/src/i18n/catalog/en/core2.js +15 -0
  93. package/src/i18n/catalog/en/ui.js +221 -0
  94. package/src/i18n/catalog/en.js +12 -0
  95. package/src/i18n/catalog/index.js +5 -0
  96. package/src/i18n/catalog/ko/cli.js +50 -0
  97. package/src/i18n/catalog/ko/commands.js +187 -0
  98. package/src/i18n/catalog/ko/copy.js +19 -0
  99. package/src/i18n/catalog/ko/core.js +74 -0
  100. package/src/i18n/catalog/ko/core2.js +15 -0
  101. package/src/i18n/catalog/ko/ui.js +221 -0
  102. package/src/i18n/catalog/ko.js +10 -0
  103. package/src/i18n/index.js +44 -0
  104. package/src/i18n/languages.js +9 -0
  105. package/src/index.js +128 -94
  106. package/src/ui/ansi.js +7 -7
  107. package/src/ui/banner.js +7 -6
  108. package/src/ui/env-plan.js +82 -81
  109. package/src/ui/prompts.js +97 -122
  110. package/src/ui/readline-engine.js +59 -58
  111. package/src/ui/status-cards.js +37 -31
  112. package/src/ui/summary.js +89 -88
@@ -1,44 +1,49 @@
1
- // wizard-prompts.yml 라벨 메타 파서.
2
- // ⚠️ YAML 라이브러리 금지 — 라인 기반 파싱만 한다(외부 의존성 0, 형식이 조금 어긋난 사용자 파일도 읽힌다).
1
+ // wizard-prompts.yml label metadata parser.
2
+ // WARNING: no YAML library - line-based parsing only (zero external dependencies, and slightly malformed user files still read).
3
3
  import { join } from "node:path";
4
4
  import * as nodeFs from "node:fs";
5
5
  import { PAYLOAD } from "./paths.js";
6
+ import { getLanguage } from "../i18n/index.js";
6
7
 
7
- // wizard-prompts.yml 위치 — 사용자 레포(커스텀 오버라이드용) 기준 상대경로
8
+ // Location of wizard-prompts.yml - path relative to the user repo (for custom overrides)
8
9
  export const LABELS_FILE = ".github/config/wizard-prompts.yml";
9
10
 
10
- // 따옴표 감싸진 값이면 벗기고 trim ("값" → 값).
11
+ // Strip surrounding quotes and trim ("value" -> value).
11
12
  function unquote(s) {
12
13
  const t = s.trim();
13
14
  if (t.startsWith('"') && t.endsWith('"') && t.length >= 2) return t.slice(1, -1);
14
15
  return t;
15
16
  }
16
17
 
17
- // wizard-prompts.yml 텍스트 → 파싱 객체 (순수 함수 — 테스트 직접 사용 가능).
18
- // 반환: { fields: Map<조회키, {label?,help?,example?}>, workflowNames: [{key,value}] }
19
- // - 조회키: "PROJECT_NAME" 또는 "flutter.APP_ARTIFACT_NAME" (dotted 타입 오버라이드)
20
- // - 구형 1줄(KEY: "라벨")은 fields의 label로 흡수 (label만 의미)
18
+ // wizard-prompts.yml text -> parsed object (pure function - usable directly in tests).
19
+ // Returns: { fields: Map<lookup key, {label?,help?,example?}>, workflowNames: [{key,value}] }
20
+ // - lookup key: "PROJECT_NAME" or "flutter.APP_ARTIFACT_NAME" (dotted per-type override)
21
+ // - the legacy one-liner (KEY: "label") is absorbed as the fields label (label only)
22
+ // - a language variant is a suffixed field (label_ko) or a suffixed names block (_workflow_names_ko);
23
+ // the plain field/block is the default-language text
21
24
  export function parseWizardPrompts(text) {
22
25
  const fields = new Map();
23
26
  const workflowNames = [];
24
- let current = null; // 현재 블록의 fields 엔트리 (들여쓰기 라인 소속처)
25
- let inWfNames = false; // _workflow_names 블록 내부 여부
27
+ let current = null; // fields entry of the current block (owner of indented lines)
28
+ let inWfNames = false; // whether inside a _workflow_names block
29
+ let wfLang = null; // language of that block (null = the plain default block)
26
30
 
27
31
  for (const raw of String(text).split(/\r?\n/)) {
28
32
  const line = raw.replace(/\r$/, "");
29
- if (!line.trim() || line.trim().startsWith("#")) continue; // 빈 줄·주석은 블록을 끊지 않음
33
+ if (!line.trim() || line.trim().startsWith("#")) continue; // blank lines and comments do not end a block
30
34
 
31
35
  if (!/^\s/.test(line)) {
32
- // 최상위 키 라인 — 이전 블록 종료
36
+ // top-level key line - ends the previous block
33
37
  current = null; inWfNames = false;
34
38
  const m = line.match(/^([A-Za-z_][A-Za-z0-9_.\-]*):(.*)$/);
35
39
  if (!m) continue;
36
40
  const key = m[1];
37
41
  const rest = m[2].trim();
38
- if (key === "_workflow_names") { inWfNames = true; continue; }
42
+ const wfBlock = key.match(/^_workflow_names(?:_([a-z]{2}))?$/);
43
+ if (wfBlock) { inWfNames = true; wfLang = wfBlock[1] ?? null; continue; }
39
44
  const entry = fields.get(key) || {};
40
45
  if (rest) {
41
- // 구형 1줄: KEY: "라벨" (label로만 사용)
46
+ // legacy one-liner: KEY: "label" (used as label only)
42
47
  const q = rest.match(/^"([^"]*)"\s*$/);
43
48
  if (q) entry.label = q[1];
44
49
  }
@@ -47,28 +52,28 @@ export function parseWizardPrompts(text) {
47
52
  continue;
48
53
  }
49
54
 
50
- // 들여쓰기 라인 — 현재 블록 소속
55
+ // indented line - belongs to the current block
51
56
  const m = line.match(/^\s+([A-Za-z_][A-Za-z0-9_.\-]*):\s*(.*)$/);
52
57
  if (!m) continue;
53
58
  if (inWfNames) {
54
- // " KEY: "값"" 형식만 인정
59
+ // only the ` KEY: "value"` form is accepted
55
60
  const q = m[2].match(/^"(.*)"\s*$/);
56
- if (q) workflowNames.push({ key: m[1], value: q[1] });
61
+ if (q) workflowNames.push(wfLang ? { key: m[1], value: q[1], lang: wfLang } : { key: m[1], value: q[1] });
57
62
  continue;
58
63
  }
59
- if (current && (m[1] === "label" || m[1] === "help" || m[1] === "example")) {
60
- // 블록 내 첫 등장만 채택
64
+ if (current && /^(?:label|help|example)(?:_[a-z]{2})?$/.test(m[1])) {
65
+ // only the first occurrence in a block is taken
61
66
  if (current[m[1]] == null) current[m[1]] = unquote(m[2]);
62
67
  }
63
68
  }
64
69
  return { fields, workflowNames };
65
70
  }
66
71
 
67
- // wizard-prompts.yml을 찾아 읽고 파싱.
68
- // 번들본(payload/config)을 바탕으로 대상 프로젝트의 사용자 파일(커스텀 오버라이드)을 키 단위로 덮어쓴다.
69
- // WHY 병합: 사용자 파일에는 바꾸고 싶은 키만 적는 것이 자연스럽다 — 파일째 대체하면 적지 않은 나머지
70
- // 질문의 label/help/example과 워크플로우 표시명이 전부 사라져 KEY명만 보인다.
71
- // fs 주입 가능(테스트용) — 기본 node:fs.
72
+ // Find, read and parse wizard-prompts.yml.
73
+ // The target project's user file (custom override) is layered over the bundled copy (payload/config) key by key.
74
+ // WHY merge: it is natural for a user file to list only the keys to change - replacing the whole file would drop the
75
+ // label/help/example of every unlisted question and the workflow display names, leaving only KEY names.
76
+ // fs is injectable (for tests) - defaults to node:fs.
72
77
  export function loadWizardPrompts(targetRoot = ".", payloadRoot = "", fs = nodeFs) {
73
78
  const read = (p) => (fs.existsSync(p) ? parseWizardPrompts(fs.readFileSync(p, "utf8")) : null);
74
79
  const bundled = payloadRoot ? read(join(payloadRoot, PAYLOAD.configDir, "wizard-prompts.yml")) : null;
@@ -77,39 +82,56 @@ export function loadWizardPrompts(targetRoot = ".", payloadRoot = "", fs = nodeF
77
82
  return mergeWizardPrompts(bundled, user);
78
83
  }
79
84
 
80
- // 번들 + 사용자 파싱 결과 병합. 같은 키는 사용자가 적은 필드만 덮어쓴다(label만 바꾸면 help/example은 번들 유지).
85
+ // Merge the bundled and user parse results. For the same key only fields the user wrote are overridden (changing only label keeps the bundled help/example).
81
86
  export function mergeWizardPrompts(base, override) {
82
87
  const fields = new Map([...base.fields].map(([k, v]) => [k, { ...v }]));
83
88
  for (const [key, entry] of override.fields) {
84
89
  const merged = { ...(fields.get(key) || {}) };
85
- for (const [f, v] of Object.entries(entry)) if (v != null && v !== "") merged[f] = v;
90
+ const given = Object.entries(entry).filter(([, v]) => v != null && v !== "");
91
+ // A plain field written by the user must win in every language, so the bundled variants of it are dropped.
92
+ // This runs before any user value is applied, so the user's own variants survive whatever order they were written in.
93
+ for (const [f] of given) {
94
+ if (!/_[a-z]{2}$/.test(f)) for (const k of Object.keys(merged)) if (k.startsWith(`${f}_`)) delete merged[k];
95
+ }
96
+ for (const [f, v] of given) merged[f] = v;
86
97
  fields.set(key, merged);
87
98
  }
88
- const overridden = new Set(override.workflowNames.map((w) => w.key));
89
- const workflowNames = [...base.workflowNames.filter((w) => !overridden.has(w.key)), ...override.workflowNames];
99
+ // A plain user name replaces the bundled name of every language (the user wrote it for their own repo);
100
+ // a language-tagged one replaces only that language.
101
+ const overridden = new Set(override.workflowNames.map((w) => `${w.key}|${w.lang ?? "*"}`));
102
+ const isOverridden = (w) => overridden.has(`${w.key}|${w.lang ?? "*"}`) || overridden.has(`${w.key}|*`);
103
+ const workflowNames = [...base.workflowNames.filter((w) => !isOverridden(w)), ...override.workflowNames];
90
104
  return { fields, workflowNames };
91
105
  }
92
106
 
93
- // 필드 조회. field: "label" | "help" | "example".
94
- // 우선순위: "{type}.KEY" 블록 → "KEY" 블록(구형 1줄 포함) → 폴백(label이면 KEY명, 아니면 "").
95
- export function wfField(prompts, type, key, field) {
107
+ // Field lookup. field: "label" | "help" | "example".
108
+ // Priority: "{type}.KEY" block -> "KEY" block (including the legacy one-liner) -> fallback (KEY name for label, otherwise "").
109
+ // Within a block the current language's variant (label_ko) comes before the plain field.
110
+ export function wfField(prompts, type, key, field, lang = getLanguage()) {
96
111
  if (prompts && prompts.fields) {
97
112
  for (const q of [`${type}.${key}`, key]) {
98
- const v = prompts.fields.get(q)?.[field];
99
- if (v != null && v !== "") return v;
113
+ const entry = prompts.fields.get(q);
114
+ for (const f of [`${field}_${lang}`, field]) {
115
+ const v = entry?.[f];
116
+ if (v != null && v !== "") return v;
117
+ }
100
118
  }
101
119
  }
102
120
  return field === "label" ? key : "";
103
121
  }
104
122
 
105
- // 워크플로우 파일명 → 사람이 읽는 짧은 이름.
106
- // _workflow_names에서 "키가 파일명에 포함되면" 그 값 사용 — 최장 키 우선(REACT-CI vs REACT-CICD 구분).
107
- // 미매칭이면 .yaml/.yml 확장자만 제거해 반환.
108
- export function workflowDisplayName(prompts, filename) {
109
- const base = String(filename).split("/").pop().split("\\").pop(); // 경로 제거
110
- let best = null; let bestLen = 0;
111
- for (const { key, value } of prompts?.workflowNames ?? []) {
112
- if (base.includes(key) && key.length > bestLen) { best = value; bestLen = key.length; }
123
+ // Workflow filename -> short human-readable name.
124
+ // From _workflow_names, use the value "when the key is contained in the filename" - longest key wins (tells REACT-CI from REACT-CICD).
125
+ // If nothing matches, return the name with only the .yaml/.yml extension removed.
126
+ // A name tagged with the current language wins over a plain one at the same length.
127
+ export function workflowDisplayName(prompts, filename, lang = getLanguage()) {
128
+ const base = String(filename).split("/").pop().split("\\").pop(); // strip the path
129
+ let best = null; let bestLen = 0; let bestTagged = false;
130
+ for (const { key, value, lang: l } of prompts?.workflowNames ?? []) {
131
+ if (l && l !== lang) continue;
132
+ if (!base.includes(key)) continue;
133
+ const tagged = Boolean(l);
134
+ if (key.length > bestLen || (key.length === bestLen && tagged && !bestTagged)) { best = value; bestLen = key.length; bestTagged = tagged; }
113
135
  }
114
136
  if (best != null) return best;
115
137
  return base.replace(/\.ya?ml$/, "");
@@ -0,0 +1,50 @@
1
+ // English messages: argument parsing, --help, entry point (bin/, src/index.js, src/cli, src/context.js).
2
+ export default {
3
+ "cli.lang.invalid": "Unsupported language '{value}' ({source}). Supported: {supported}",
4
+ "cli.lang.defaultNotice": "Workflow messages now default to English. Use --lang ko to keep Korean.",
5
+ "cli.lang.missing": "--lang requires a value. Supported: {supported}",
6
+ "cli.lang.help": "Message language: {supported} (default: en)",
7
+ "cli.bin.nodeVersion": "Node.js 20.12 or later is required (current: {current})",
8
+ "cli.help.text": "project-auto-wizard — One command DevOps: GitHub-native release automation setup wizard\n\nUsage:\n npx project-auto-wizard [options]\n\nOptions:\n -m, --mode MODE Unified mode (full | uninstall | status | doctor)\n Default: interactive. full = install and update\n uninstall = full removal (interactive checklist; with --force, opt in via --purge-*)\n status = check install state and drift (read-only). doctor = environment diagnosis (read-only)\n -t, --type CSV Project types as csv (e.g. spring,react,python)\n Supported: {types}\n --project-version V Initial version of the target (e.g. 1.0.0). Auto-detected when omitted\n --paths \"t=p,...\" Per-type project paths (monorepo). e.g. flutter=app,react=client\n --main-branch B Release branch (default: detected default branch)\n --develop-branch B Development branch (default: develop). Same as the release branch = trunk-based mode\n --deploy-style STYLE Server deploy style: simple | nginx | traefik | none (default: simple)\n --flutter-env-mode MODE Flutter env var mode: dart-define | dotenv (default: dart-define for new installs; existing installs keep the saved value / dotenv)\n --flutter-store CSV Flutter store deploy targets: android,ios | android | ios | none (default: install both)\n --android-deploy-mode MODE Play Store deploy mode: store_only | store_prepare | store_submit (default: store_only)\n --ios-deploy-mode MODE iOS deploy mode: store_only | store_prepare | store_submit (default: store_only)\n --semver-auto / --no-semver-auto Auto major/minor/patch bump from commit types (default: enabled)\n --copilot / --no-copilot Generate the AI summary with Copilot (default: off; consumes GitHub Copilot AI Credits)\n --lang LANG {langHelp}\n --force Required for full; non-interactive removal for uninstall (skips all confirmations, uses defaults)\n --dry-run Preview what would change without touching any file (supported by full/uninstall)\n --purge-readme With --mode uninstall --force, also remove the README.md version section\n --purge-gitignore With --mode uninstall --force, also remove the auto-added .gitignore entries\n --purge-version With --mode uninstall --force, also remove version.yml\n -v, --version Print the project-auto-wizard version\n -h, --help Show this help\n\nExamples:\n npx project-auto-wizard --mode full --force --type spring,react\n npx project-auto-wizard --mode full --force --type flutter --paths \"flutter=app\"\n npx project-auto-wizard --mode status\n npx project-auto-wizard --mode doctor\n npx project-auto-wizard --mode full --force --type node --dry-run\n npx project-auto-wizard --mode uninstall --force --purge-readme --purge-gitignore --purge-version\n",
9
+ "cli.args.projectVersionInvalid": "Invalid --project-version value: '{raw}' (x.y.z format, e.g. 1.0.0)",
10
+ "cli.args.typeUnsupported": "Unsupported type: '{type}'\nSupported types: {valid}",
11
+ "cli.args.typeEmpty": "The --type argument is empty",
12
+ "cli.args.noValue": "(none)",
13
+ "cli.args.deployStyleInvalid": "Invalid --deploy-style value: {value} ({choices})",
14
+ "cli.args.semverConflict": "--semver-auto and --no-semver-auto cannot be specified together",
15
+ "cli.args.copilotConflict": "--copilot and --no-copilot cannot be specified together",
16
+ "cli.args.pathsEmpty": "The --paths argument is empty (e.g. --paths flutter=app,react=client)",
17
+ "cli.args.branchEmpty": "{flag} cannot be empty",
18
+ "cli.args.branchInvalid": "{flag} value is not a valid branch name: '{value}'",
19
+ "cli.args.flagNoValue": "{flag} does not take a value (got {flag}={value})",
20
+ "cli.args.unknownOption": "Unknown option: {option}",
21
+ "cli.args.modeUnsupported": "Unsupported mode: '{mode}'\nSupported modes: interactive full uninstall status doctor",
22
+ "cli.args.pathsTypeUnsupported": "Unsupported type in --paths: '{type}'",
23
+ "cli.args.pathsRelativeOnly": "--paths accepts only paths relative to the repo: '{pair}'",
24
+ "cli.index.purgePrompt": "To run purge, type this repo name exactly: {repoName}\n> ",
25
+ "cli.index.dryRunNeedsMode": "Use --dry-run together with --mode <full|uninstall> (it is not supported in interactive mode).",
26
+ "cli.index.noTty": "Interactive input is not available in this environment. Specify --mode <full|uninstall> and --force.",
27
+ "cli.index.ignoredFlags": "Interactive mode does not use {flags}; choose them in the questions or use them with --mode full --force.",
28
+ "cli.index.purgeNotGit": "Not a git repository (no .git); purge can only run inside a git repository.",
29
+ "cli.index.deleteDevelopSkipDry": "(--delete-develop-branch given: this is a trunk-based setup (develop === main), so the real run will skip the deletion too)",
30
+ "cli.index.deleteDevelopTryDry": "(--delete-develop-branch given: the real run will also try to delete the local develop branch)",
31
+ "cli.index.purgeNeedsYes": "purge cannot run without --yes (--force cannot replace it).",
32
+ "cli.index.purgeGitStatusFailed": "Could not check the git status; aborting purge for safety.",
33
+ "cli.index.purgeDirty": "The working tree has uncommitted changes, which cannot be recovered after purge. Commit them or use --allow-dirty.",
34
+ "cli.index.forceRequiredNonTty": "The --force option is required in a non-interactive environment.",
35
+ "cli.index.purgeRepoMismatch": "The repo name you typed does not match; aborting purge.",
36
+ "cli.index.deleteDevelopSkip": "This is a trunk-based setup (develop === main); skipping deletion of the release branch.",
37
+ "cli.index.reasonUnknown": "reason unknown",
38
+ "cli.index.deleteDevelopFailed": "Failed to delete local branch '{branch}' ({reason}); please check it manually.",
39
+ "cli.index.deleteDevelopDone": "Deleted local branch '{branch}'.",
40
+ "cli.index.removedWorkflows": "{n} workflows",
41
+ "cli.index.removedScripts": "{n} scripts",
42
+ "cli.index.removedAppFiles": "{n} Flutter app files",
43
+ "cli.index.removedReadme": "README version section",
44
+ "cli.index.removedGitignore": "auto-added .gitignore entries",
45
+ "cli.index.removed": "Removed: {removed}",
46
+ "cli.index.forceRequired": "This mode cannot run without --force (there is no confirmation step).",
47
+ "cli.index.mainBranchHint": "If this is wrong, specify it with --main-branch.",
48
+ "cli.index.deployFallback": "{types} has no {style} zero-downtime deploy workflow, so it is installed with the single-server deploy (simple).",
49
+ "cli.index.aborted": "Aborted; exiting without changes.",
50
+ };
@@ -0,0 +1,187 @@
1
+ // English messages: commands (status, doctor, dry-run, full, uninstall, purge).
2
+ export default {
3
+ "cmd.status.title": "project-auto-wizard status — install state",
4
+ "cmd.status.notInstalled": "project-auto-wizard is not installed in this directory (no version.yml).",
5
+ "cmd.status.version": "Version : {value}",
6
+ "cmd.status.templateVersion": "Template version: {value}",
7
+ "cmd.status.types": "Project types : {value}",
8
+ "cmd.status.none": "(none)",
9
+ "cmd.status.branchMode": "Branch mode : {mode} ({main} / {develop})",
10
+ "cmd.status.unsetDefaultFalse": "unset (default false)",
11
+ "cmd.status.options": "Options : {value}",
12
+ "cmd.status.modified": "Workflow files modified by the user ({n}):",
13
+ "cmd.status.unmodified": "All workflow files match their install-time defaults (no modifications).",
14
+ "cmd.status.stale": "Old workflows not in the current version ({n}; cleaned up on the next update):",
15
+ "cmd.status.bucketsTitle": "If you update now:",
16
+ "cmd.status.bucketAuto": " Upstream changed - auto-applicable {n}",
17
+ "cmd.status.bucketLocalKept": " Edited by me - upstream unchanged {n} (kept)",
18
+ "cmd.status.bucketConflicts": " Changed on both sides - needs review {n}",
19
+ "cmd.status.bucketRemoved": " Deleted by me - not restored {n}",
20
+ "cmd.doctor.docPath.postInstall": "/start/quickstart/#post-install",
21
+ "cmd.doctor.docPath.flutterStore": "/project-types/flutter/#flutter-store",
22
+ "cmd.doctor.install.name": "Installed",
23
+ "cmd.doctor.install.label": "Install status",
24
+ "cmd.doctor.install.purpose": "Whether the wizard is installed in this folder",
25
+ "cmd.doctor.install.value": "version.yml found",
26
+ "cmd.doctor.install.note": "Not installed in this folder yet; you can install now.",
27
+ "cmd.doctor.gh.purpose": "For reading repo settings",
28
+ "cmd.doctor.gh.notFound": "The gh CLI was not found.",
29
+ "cmd.doctor.gh.notFoundImpact": "Repo permissions and secrets cannot be read, so all remote checks below are skipped.",
30
+ "cmd.doctor.gh.notFoundAction": "Install the gh CLI from https://cli.github.com/ and run again",
31
+ "cmd.doctor.gh.installed": "installed",
32
+ "cmd.doctor.auth.name": "gh auth",
33
+ "cmd.doctor.auth.label": "GitHub login",
34
+ "cmd.doctor.auth.purpose": "Permission to read repo settings",
35
+ "cmd.doctor.auth.notLoggedIn": "Not logged in.",
36
+ "cmd.doctor.auth.impact": "Repo settings cannot be read, so all remote checks below are skipped.",
37
+ "cmd.doctor.auth.action": "Run `gh auth login` in a terminal",
38
+ "cmd.doctor.auth.ok": "authenticated",
39
+ "cmd.doctor.remote.name": "GitHub remote",
40
+ "cmd.doctor.remote.purpose": "Identify the repo to check",
41
+ "cmd.doctor.remote.notFound": "Could not find a GitHub owner/repo in the origin remote.",
42
+ "cmd.doctor.remote.impact": "It is unknown which repo to check, so all remote checks below are skipped.",
43
+ "cmd.doctor.remote.action": "Check with `git remote -v` that origin points to a GitHub address",
44
+ "cmd.doctor.perm.purpose": "Default permissions for workflows you add yourself",
45
+ "cmd.doctor.adminImpact": "This setting cannot be read without repo admin rights; the value itself may be fine.",
46
+ "cmd.doctor.perm.lookupFailed": "Could not read the setting.",
47
+ "cmd.doctor.perm.action": "Ask a repo admin to check Settings → Actions → General → Workflow permissions",
48
+ "cmd.doctor.perm.unknown": "unknown",
49
+ "cmd.doctor.perm.infoCurrent": "It is currently {value}; the workflows installed by the wizard each declare their own permissions, so they work as they are.",
50
+ "cmd.doctor.perm.infoAdvice": "A workflow you add yourself that omits permissions follows this default; raise it to Read and write only in that case.",
51
+ "cmd.doctor.pat.purpose": "Automatic tag and Release publishing",
52
+ "cmd.doctor.pat.registered": "registered",
53
+ "cmd.doctor.pat.note1": "Without the secret, the fallback takes over automatically and still carries through tag and Release publishing and the main deploy workflow; it only takes up to ~20 seconds longer after the actual merge.",
54
+ "cmd.doctor.pat.note2": "If you want it faster, you can register a PAT; issue it from an organization bot/machine account, never a personal account (scopes: repo, workflow).",
55
+ "cmd.doctor.pat.note3": "Register: repo Settings → Secrets and variables → Actions → New repository secret · name it WORKFLOW_PAT",
56
+ "cmd.doctor.merge.name": "automerge compatibility (merge commits allowed)",
57
+ "cmd.doctor.merge.label": "Merge commits allowed",
58
+ "cmd.doctor.merge.purpose": "Condition for auto-merging the release PR",
59
+ "cmd.doctor.merge.lookupFailed": "Could not read the setting.",
60
+ "cmd.doctor.merge.lookupAction": "Ask a repo admin to check Settings → General → Pull Requests",
61
+ "cmd.doctor.merge.allowed": "allowed",
62
+ "cmd.doctor.merge.disabled": "Merge commits are turned off in this repo.",
63
+ "cmd.doctor.merge.impact": "RELEASE-PUBLISH detects releases from the merge commit title, so the auto-merge flow may break.",
64
+ "cmd.doctor.merge.action1": "Repo Settings → General → Pull Requests",
65
+ "cmd.doctor.merge.action2": "Check Allow merge commits",
66
+ "cmd.doctor.copilot.on": "It is on (copilot_ai: true in version.yml).",
67
+ "cmd.doctor.copilot.off": "It is off (copilot_ai: false in version.yml); to turn it on, reinstall with --copilot or use the interactive 'Modify > Copilot AI summary'.",
68
+ "cmd.doctor.copilot.default": "It is off by default (copilot_ai: false in version.yml).",
69
+ "cmd.doctor.copilot.name": "Copilot AI summary",
70
+ "cmd.doctor.copilot.purpose": "AI release note generation (optional)",
71
+ "cmd.doctor.copilot.creditsOn": "GitHub Copilot AI Credits are consumed; organizations need the 'Allow use of Copilot CLI billed to the organization' policy.",
72
+ "cmd.doctor.copilot.creditsOff": "Turning it on consumes GitHub Copilot AI Credits; organizations need the 'Allow use of Copilot CLI billed to the organization' policy.",
73
+ "cmd.doctor.copilot.fallback": "When it is off or unavailable, it switches to the rule-based summary automatically, so you can leave it as is.",
74
+ "cmd.doctor.heading": "Environment check",
75
+ "cmd.doctor.details": "Details: ",
76
+ "cmd.doctor.summaryNone": "No problems found.",
77
+ "cmd.doctor.summaryFail": "Found problems in {n} item(s); some checks could not be run.",
78
+ "cmd.doctor.summaryWarn": "Found problems in {n} item(s).",
79
+ "cmd.doctor.summaryWarnNote": "You can install right now, and the {n} above can be set up later.",
80
+ "cmd.dryRun.header": "project-auto-wizard --dry-run (mode: {mode}) — preview, no files were changed",
81
+ "cmd.dryRun.uninstall.workflows": "Workflows to be removed ({n}):",
82
+ "cmd.dryRun.uninstall.scripts": "Scripts to be removed ({n}):",
83
+ "cmd.dryRun.uninstall.appFile": "Flutter app file to be removed: {file}",
84
+ "cmd.dryRun.uninstall.readme": "To be removed: README.md version section (AUTO-VERSION-SECTION)",
85
+ "cmd.dryRun.uninstall.gitignore": "To be removed: auto-added .gitignore entries",
86
+ "cmd.dryRun.uninstall.versionYml": "File to be removed: version.yml",
87
+ "cmd.dryRun.full.newFiles": "New files ({n}):",
88
+ "cmd.dryRun.full.changed": "Files to be changed ({n}; a conflict if the existing install is a user-modified copy):",
89
+ "cmd.dryRun.full.autoUpdated": "Auto-updated files ({n}; unmodified copies replaced with the latest):",
90
+ "cmd.dryRun.full.localKept": "Kept as-is ({n}; your edits stay, upstream is unchanged):",
91
+ "cmd.dryRun.full.removed": "Deleted by you, not restored ({n}):",
92
+ "cmd.dryRun.full.unchanged": "Identical files ({n}, no change)",
93
+ "cmd.dryRun.reason.cleanup": "cleanup of the previous deploy style",
94
+ "cmd.dryRun.reason.storeCleanup": "cleanup of deselected store workflows",
95
+ "cmd.dryRun.reason.staleCleanup": "cleanup of old workflows not in the current version",
96
+ "cmd.dryRun.cleanup.removedLine": " - {file} ({reason})",
97
+ "cmd.dryRun.cleanup.backedUpLine": " > {file} → {file}.bak ({reason}; backed up because it was modified)",
98
+ "cmd.dryRun.cleanup.removedHeading": "Files to be deleted ({n}):",
99
+ "cmd.dryRun.cleanup.backedUpHeading": "Files to be moved to .bak ({n}):",
100
+ "cmd.dryRun.gitignore.created": ".gitignore: will be created ({added})",
101
+ "cmd.dryRun.gitignore.append": ".gitignore: will add {added}",
102
+ "cmd.dryRun.gitignore.unchanged": ".gitignore: no change (entries already present)",
103
+ "cmd.dryRun.flutter.created": "Flutter store deploy files — new ({n}):",
104
+ "cmd.dryRun.flutter.kept": "Flutter store deploy files — existing files kept ({n}, not overwritten):",
105
+ "cmd.dryRun.flutter.keptLine": " = {file} (existing file kept)",
106
+ "cmd.dryRun.versionYml.update": "version.yml: will be updated",
107
+ "cmd.dryRun.versionYml.unchanged": "version.yml: no change",
108
+ "cmd.dryRun.versionYml.create": "version.yml: will be created",
109
+ "cmd.dryRun.versionYml.note": " (Note: for types with deploy setting questions (spring etc.), the deploy: block is not reflected in the preview, so it may look different from the real install.)",
110
+ "cmd.dryRun.scripts.create": "new",
111
+ "cmd.dryRun.scripts.overwrite": "overwrites the existing file with the new version; your own edits are lost",
112
+ "cmd.dryRun.scripts.unchanged": "no change",
113
+ "cmd.dryRun.scripts.heading": "Scripts ({dir}/, {n}; always replaced with the new version):",
114
+ "cmd.dryRun.readme.added": "README.md: a version section will be appended at the end",
115
+ "cmd.dryRun.readme.skipNoReadme": "README.md: no file, so no version section is added",
116
+ "cmd.dryRun.readme.skipMarker": "README.md: a version section already exists, no change",
117
+ "cmd.dryRun.readme.skipVersionLine": "README.md: a version line already exists, no change",
118
+ "cmd.dryRun.readme.other": "README.md: {status}",
119
+ "cmd.dryRun.baseline.update": "{path}: will be updated (reference for the next update)",
120
+ "cmd.dryRun.baseline.create": "{path}: will be created (reference for the next update)",
121
+ "cmd.full.noWritePermission": "Installation did not start because write permission is missing (no files were changed):\n{list}\nCheck the permissions and run again.",
122
+ "cmd.full.log.typeEvidence": "{type} (evidence: {evidence})",
123
+ "cmd.full.log.userChosen": "chosen by user",
124
+ "cmd.full.log.keepExisting": "{file} (existing file kept)",
125
+ "cmd.full.log.versionUnchanged": "version.yml (v{version}, code={code}, no change)",
126
+ "cmd.full.log.scriptOverwritten": " (differed from the existing content, overwritten with the new version)",
127
+ "cmd.full.log.bytecodeRemoved": "{file} (bytecode committed by an earlier version; commit the deletion too)",
128
+ "cmd.full.log.gitignoreExisting": ".gitignore (entries already present)",
129
+ "cmd.full.log.secretOptional": "{name} (optional) ← {users}",
130
+ "cmd.full.summary.installed": "Installed",
131
+ "cmd.full.summary.installedValue": "{n} files",
132
+ "cmd.full.summary.autoUpdated": "Auto-updated",
133
+ "cmd.full.summary.autoUpdatedValue": "{n} (not modified by the user)",
134
+ "cmd.full.summary.kept": "Kept",
135
+ "cmd.full.summary.keptValue": "{n} (user-modified copies)",
136
+ "cmd.full.summary.unchanged": "Unchanged",
137
+ "cmd.full.summary.unchangedValue": "{n}",
138
+ "cmd.full.summary.backup": "Backup replaced",
139
+ "cmd.full.summary.backupValue": "{n} (.bak created)",
140
+ "cmd.full.summary.cleanup": "Cleanup",
141
+ "cmd.full.summary.cleanupValue": "{removed} deleted, {backedUp} moved to .bak",
142
+ "cmd.full.summary.unresolved": "Unresolved",
143
+ "cmd.full.summary.unresolvedValue": "{n}",
144
+ "cmd.full.summary.unresolvedActionValue": "{n} <- action needed",
145
+ "cmd.full.summary.secrets": "Required Secrets",
146
+ "cmd.full.summary.secretsValue": "{n}",
147
+ "cmd.full.summary.result": "Result",
148
+ "cmd.full.summary.resultWarn": "Attention ({n} unresolved)",
149
+ "cmd.full.notice.staleHeading": "Cleaned up old workflows not in the current version (renamed or removed files):",
150
+ "cmd.full.notice.staleRemoved": " • {file} — deleted (unmodified file)",
151
+ "cmd.full.notice.staleBackedUp": " • {file} → {file}.bak — backed up because you had modified it",
152
+ "cmd.full.notice.conflictKept": "{n} conflict(s): kept the existing files (upstream changes not applied): {files}",
153
+ "cmd.full.notice.conflictHint": " To choose per file, run again in interactive mode (npx project-auto-wizard).",
154
+ "cmd.uninstall.gitignoreDetail": "auto-added .gitignore entries ({status})",
155
+ "cmd.uninstall.item.workflows": "Workflows (.github/workflows/PROJECT-*.yaml) + install records (.github/.wizard) + unmodified Flutter app files",
156
+ "cmd.uninstall.item.scripts": "Scripts (.github/scripts/*.py)",
157
+ "cmd.uninstall.item.readme": "README.md version section (AUTO-VERSION-SECTION)",
158
+ "cmd.uninstall.item.gitignore": "Auto-added .gitignore entries",
159
+ "cmd.uninstall.item.versionYml": "version.yml (all version/branch settings)",
160
+ "cmd.uninstall.noneSelected": "(no items selected)",
161
+ "cmd.uninstall.result.workflows": "Removed {n} workflows",
162
+ "cmd.uninstall.result.scripts": "Removed {n} scripts",
163
+ "cmd.uninstall.result.appFiles": "Removed {n} Flutter app files",
164
+ "cmd.uninstall.result.readme": "Removed the README.md version section",
165
+ "cmd.uninstall.result.gitignore": "Removed auto-added .gitignore entries",
166
+ "cmd.uninstall.result.versionYml": "Removed version.yml",
167
+ "cmd.uninstall.result.none": "Nothing was removed.",
168
+ "cmd.uninstall.flow.nothing": "Nothing to remove.",
169
+ "cmd.uninstall.flow.title": "Full removal",
170
+ "cmd.uninstall.flow.select": "Select the items to delete (Space to toggle, Enter to confirm)",
171
+ "cmd.uninstall.flow.cancelled": "Full removal cancelled.",
172
+ "cmd.uninstall.flow.plannedTitle": "Items to be deleted",
173
+ "cmd.uninstall.flow.confirm": "Really delete? This cannot be undone.",
174
+ "cmd.uninstall.flow.doneTitle": "Full removal complete",
175
+ "cmd.purge.headerDry": "project-auto-wizard --mode purge --dry-run — preview, no files were changed",
176
+ "cmd.purge.header": "project-auto-wizard --mode purge — removing the items below",
177
+ "cmd.purge.workflows": "Workflows ({n}):",
178
+ "cmd.purge.scripts": "Scripts ({n}):",
179
+ "cmd.purge.appFile": "Flutter app file: {file}",
180
+ "cmd.purge.versionYml": "File: version.yml",
181
+ "cmd.purge.readmeSection": "README.md: AUTO-VERSION-SECTION block",
182
+ "cmd.purge.gitignore": ".gitignore: auto-added entries (*.bak, *.template.yaml)",
183
+ "cmd.purge.gitignoreKept": ".gitignore: auto-added entries kept (they hide backup files of the workflows that were left)",
184
+ "cmd.purge.file": "File: {file}",
185
+ "cmd.purge.gitignoreLog": "auto-added .gitignore entries",
186
+ "cmd.purge.removedHeading": "Removed:",
187
+ };
@@ -0,0 +1,19 @@
1
+ // English messages: copy area (src/core/copy).
2
+ export default {
3
+ "copy.readme.status.added": "Appended version section to the end of README.md",
4
+ "copy.readme.status.skipNoReadme": "README.md not found; version section not added",
5
+ "copy.readme.status.skipMarker": "Version section already present; left as is",
6
+ "copy.readme.status.skipVersionLine": "Version line already present; left as is",
7
+ "copy.readme.versionHeading": "## Latest Version : v{version}",
8
+ "copy.readme.historyLink": "[View full version history](CHANGELOG.md)",
9
+ "copy.gitignore.newFileHeader": "# project-auto-wizard: backup files created during conflict handling (safe to ignore)",
10
+ "copy.workflows.error.noPayloadWorkflows": "Package structure error: could not find the payload/workflows folder.",
11
+ "copy.workflows.log.keepLocal": "{f} (upstream unchanged, keeping user-edited copy)",
12
+ "copy.workflows.log.autoUpdate": "{f} (not modified by user, replaced with latest)",
13
+ "copy.workflows.log.restore": "{f} (deleted by user, restore chosen)",
14
+ "copy.workflows.log.removedKept": "{f} (deleted by user, not restored)",
15
+ "copy.workflows.log.backup": "{filename} → {filename}.bak (user decision, replaced with new version)",
16
+ "copy.workflows.log.template": "{filename} kept + {templateName} created (user decision)",
17
+ "copy.workflows.log.skipDecided": "{filename} (user decision: keep existing, upstream changes not applied)",
18
+ "copy.workflows.log.skipForce": "{filename} (--force default: keep existing, upstream changes not applied)",
19
+ };
@@ -0,0 +1,74 @@
1
+ // English messages: core area (detect, paths, branches, deploy-style, flutter-*, ...).
2
+ export default {
3
+ "core.detect.versionFallbackHint": "Set it with --project-version or check version.yml.",
4
+ "core.detect.versionFallbackWarn": "⚠️ Could not detect the version automatically, using the default 0.0.1 — {tail}",
5
+ "core.detect.buildNumber.pubspecMissing": "⚠️ pubspec.yaml has no build number (+N), so version_code could not be detected — using the default 1. Check your actual build number.",
6
+ "core.detect.buildNumber.gradleMissing": "⚠️ android/app/build.gradle has no versionCode, so version_code could not be detected — using the default 1. Check your actual build number.",
7
+ "core.detect.buildNumber.expoMissing": "⚠️ expo.android.versionCode is missing in app.json, so version_code could not be detected — using the default 1. Check your actual build number.",
8
+ "core.detectFs.monorepoWarn": "⚠️ No project files found at the root, installing as basic. Found in subfolders: {list}\n For a monorepo, run again with --paths \"{hint}\".",
9
+ "core.detectFs.defaultBranchWarn": "⚠️ Could not determine the remote default branch (e.g. an empty remote repo), assuming '{fallback}' as the release branch.{hint}",
10
+ "core.branches.developMissing": "The remote has no '{develop}' branch — commit the installed files, push '{main}', then create it: git push origin {main}:{develop}",
11
+ "core.branches.confirmCreate": "The remote has no '{develop}' branch. Create it from the current HEAD and push?",
12
+ "core.branches.alreadyExists": "already exists",
13
+ "core.branches.localSkipped": "Skipped creating local branch '{develop}' ({reason})",
14
+ "core.branches.pushFailed": "⚠️ Failed to push branch '{develop}' — check the remote settings, then push manually (git push -u origin {develop})",
15
+ "core.branches.created": "Created and pushed branch '{develop}'.",
16
+ "core.assets.missingWorkflows": "Package structure error — payload/workflows folder not found.",
17
+ "core.assets.missingScripts": "Package structure error — payload/scripts folder not found.",
18
+ "core.branding.unknownPlaceholder": "Unknown placeholder left over: {{{name}}}",
19
+ "core.deploy.label.simple": "Single-server deploy — stops and restarts the container (simplest, short downtime)",
20
+ "core.deploy.label.nginx": "Zero-downtime deploy (Nginx) — toggles the nginx config proxy_pass port between Blue/Green",
21
+ "core.deploy.label.traefik": "Zero-downtime deploy (Traefik) — switches Blue/Green through Traefik routing",
22
+ "core.flutterOptions.storeSubmitWarning": "Choosing store_submit submits a store review automatically on every main push.",
23
+ "core.flutterHooks.status.envModeUnset": "unset (keeps dotenv)",
24
+ "core.flutterHooks.status.storeUnset": "unset (installs both)",
25
+ "core.flutterHooks.status.deployModeUnset": "unset (store_only)",
26
+ "core.flutterHooks.comment.envMode": "(how Flutter environment variables are injected)",
27
+ "core.flutterHooks.comment.store": "(store deploy targets)",
28
+ "core.flutterHooks.comment.androidDeployMode": "(Play Store deploy mode)",
29
+ "core.flutterHooks.comment.iosDeployMode": "(iOS deploy mode)",
30
+ "core.flutterHooks.err.invalidFlag": "Invalid value for {flag}: {value} ({allowed})",
31
+ "core.flutterHooks.noValue": "(none)",
32
+ "core.flutterHooks.log.storesNone": "none",
33
+ "core.flutterHooks.log.storesUndecided": "undecided (both)",
34
+ "core.flutterDoctor.row.android": "Flutter Android deploy files",
35
+ "core.flutterDoctor.row.ios": "Flutter iOS deploy files",
36
+ "core.flutterDoctor.purpose.storeFiles": "Files required for the fastlane store upload",
37
+ "core.flutterDoctor.value.missing": "Missing files: {files}",
38
+ "core.flutterDoctor.impact.missing": "Without these files the store deploy workflow fails at the fastlane step.",
39
+ "core.flutterDoctor.action.missing": "Run the wizard again to recreate only the missing files (existing files are not overwritten)",
40
+ "core.flutterDoctor.value.present": "{count} present",
41
+ "core.flutterDoctor.purpose.exportOptions": "iOS signing and export settings",
42
+ "core.flutterDoctor.value.unfilled": "Unfilled values: {left}",
43
+ "core.flutterDoctor.impact.unfilled": "If left unfilled, the IOS-TESTFLIGHT workflow stops at the ExportOptions.plist validation step.",
44
+ "core.flutterDoctor.action.unfilled": "Replace the placeholders in {path} with real values (Team ID, bundle ID, provisioning profile name)",
45
+ "core.flutterDoctor.value.noPlaceholder": "No placeholders",
46
+ "core.paths.intro.multi": "🔍 Multi-type project detected — {total} types in total",
47
+ "core.paths.intro.single": "🔍 {type} project detected — 1 type in total",
48
+ "core.paths.intro.rootDef": "💡 'Project root' = the folder that holds that type's version file (relative to the repo root)",
49
+ "core.paths.err.pathMissing": "The path given with --paths does not exist: '{type}={path}'",
50
+ "core.paths.say.explicit": " {type} → {path} (set by --paths)",
51
+ "core.paths.warn.noMarker": " ⚠️ {path} has no {type} project file ({marker}) — check that the path is correct.",
52
+ "core.paths.say.rootMarker": " {type} → . ({marker} at the root)",
53
+ "core.paths.say.keepExisting": " {type} → {path} (kept from existing project_paths)",
54
+ "core.paths.say.auto": " {type} → {path} (auto-detected)",
55
+ "core.paths.err.none": "{type}: could not find a project path. Set it directly with --paths \"{type}=path\".",
56
+ "core.paths.err.ambiguous": "{type}: {count} path candidates make it ambiguous ({list}). Set it directly with --paths \"{type}=path\".",
57
+ "core.paths.found.one": " {prog} 🔍 {type} — found {marker}",
58
+ "core.paths.found.location": " Location: <repo-root>/{file}",
59
+ "core.paths.confirm.candidate": " Set the {type} project root to '{cand}'? (based on {file} — choose No to enter it manually)",
60
+ "core.paths.found.many": " {prog} 🔍 {type}: found {count} path candidates",
61
+ "core.paths.manualInput": "Enter manually",
62
+ "core.paths.select.root": " Select the {type} project root",
63
+ "core.paths.found.none": " ⚠️ {prog} {type}: no project found (maxdepth 3).",
64
+ "core.paths.prompt.base": " Enter the {type} project root path (the folder containing {marker}, e.g. server, app — press Enter for the root",
65
+ "core.paths.prompt.current": ", current: {existing}",
66
+ "core.paths.warn.outsideRepo": " ⚠️ '{input}' is outside the repo — enter a path relative to the repo root.",
67
+ "core.paths.warn.noFile": " ⚠️ {input}/{marker} does not exist.",
68
+ "core.paths.confirm.useAnyway": " Use this path anyway? (No = enter again)",
69
+ "core.paths.say.chosen": " ✅ {type} → {chosen}",
70
+ "core.paths.summary.title": "📂 Version file path per type:",
71
+ "core.paths.summary.row": " {type} → {file}",
72
+ "core.paths.dup.warn": " ⚠️ Several types ({types}) point at the same file ({file}).",
73
+ "core.paths.dup.note": " → sync writes the same version to all of them. This works fine, but check that it is the setup you intended.",
74
+ };
@@ -0,0 +1,15 @@
1
+ // English messages: core area (part 2).
2
+ export default {
3
+ "core.breakingCheck.confirm": "Have you reviewed the breaking changes above and want to continue?",
4
+ "core.breakingCheck.nonInteractive": "⚠️ There are CRITICAL breaking changes - continuing because this is a non-interactive run. Be sure to review the notes above.",
5
+ "core.logger.error.nameExhausted": "All log file names are in use: {base}",
6
+ "core.logger.warn.startFailed": "Could not start the run log: {message}",
7
+ "core.logger.warn.writeStopped": "Stopping run log writes: {message}",
8
+ "core.logger.summary.title": "=== Summary ===",
9
+ "core.removalExec.readmeSection": "README.md version section",
10
+ "core.verify.eitherSep": " or ",
11
+ "core.versionYml.error.templateRequired": "The version.yml.template source text is required (is payload/version.yml.template missing?)",
12
+ "core.versionYml.error.unknownPlaceholder": "Unknown placeholder in version.yml.template: {{{name}}}",
13
+ "core.versionYml.pathsComment": "Project folder per type (path relative to the repo root)",
14
+ "core.versionYml.deployComment": "Deploy settings remembered by the wizard (non-sensitive / editable by hand)",
15
+ };