mimi-seed 0.5.0 → 0.6.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.
package/dist/index.js CHANGED
@@ -8,23 +8,29 @@ import {
8
8
  MCP_PKG,
9
9
  cmdDeploy,
10
10
  cmdSetup,
11
+ credLabel,
12
+ credNote,
11
13
  deleteConfig,
12
14
  detectAll,
13
15
  detectHints,
14
16
  getEffectiveConfig,
15
17
  hasAnyProjectSignal,
18
+ isLang,
16
19
  isSatisfied,
17
20
  migrateLegacyJenkins,
21
+ resolveLang,
18
22
  runMcpBin,
23
+ t,
19
24
  tryCredById,
20
- writeConfig
21
- } from "./chunk-T757WVSG.js";
25
+ writeConfig,
26
+ writeSettings
27
+ } from "./chunk-R3LS4FY2.js";
22
28
 
23
29
  // src/index.ts
24
30
  import os3 from "os";
25
31
  import fs5 from "fs";
26
32
  import path5 from "path";
27
- import kleur8 from "kleur";
33
+ import kleur9 from "kleur";
28
34
  import open from "open";
29
35
 
30
36
  // src/handshake.ts
@@ -179,78 +185,81 @@ function manifestDetail(id, svc) {
179
185
  }
180
186
  async function cmdDoctor() {
181
187
  const cwd = process.cwd();
182
- process.stdout.write(kleur.bold("mimi-seed doctor\n\n"));
183
- section("\uC778\uC99D");
188
+ const m = t().doctor;
189
+ process.stdout.write(kleur.bold(m.title + "\n\n"));
190
+ section(m.secAuth);
184
191
  const cfg = await getEffectiveConfig();
185
192
  if (!cfg) {
186
- fail("Mimi Seed \uD1A0\uD070 \uC5C6\uC74C", "`mimi-seed init` \uC2E4\uD589 \uD544\uC694");
193
+ fail(m.noToken, m.noTokenFix);
187
194
  } else {
188
- ok("\uD1A0\uD070 \uC800\uC7A5\uB428", `${cfg.prefix}\u2026 (${cfg.createdAt.slice(0, 10)})`);
189
- ok("\uC5D4\uB4DC\uD3EC\uC778\uD2B8", cfg.endpoint);
195
+ ok(m.tokenSaved, `${cfg.prefix}\u2026 (${cfg.createdAt.slice(0, 10)})`);
196
+ ok(m.endpoint, cfg.endpoint);
190
197
  if (process.env.MIMI_SEED_TOKEN) {
191
- ok("CI \uBAA8\uB4DC", "MIMI_SEED_TOKEN \uD658\uACBD\uBCC0\uC218 \uC0AC\uC6A9 \uC911");
198
+ ok(m.ciMode, m.ciModeDetail);
192
199
  }
193
200
  const r = await mcpCall(cfg.endpoint, cfg.token, "list_apps", {});
194
201
  if (r.isError) {
195
- fail("\uD1A0\uD070 \uAC80\uC99D \uC2E4\uD328", r.text.slice(0, 80));
202
+ fail(m.tokenInvalid, r.text.slice(0, 80));
196
203
  } else {
197
204
  const lines = r.text.split("\n").filter(Boolean);
198
- ok("Mimi Seed \uC11C\uBC84 \uC5F0\uACB0\uB428", `\uC571 ${lines.length}\uAC1C`);
205
+ ok(m.serverOk, m.appCount(lines.length));
199
206
  }
200
207
  }
201
- section("\uB85C\uCEEC \uC790\uACA9\uC99D\uBA85 (~/.mimi-seed)");
208
+ section(m.secCreds);
202
209
  migrateLegacyJenkins();
203
210
  const detected = detectAll();
204
211
  for (const spec of CREDENTIALS) {
205
212
  const d = detected.get(spec.id);
206
- const label = spec.note ? `${spec.label} (${spec.note})` : spec.label;
207
- if (d.present) ok(spec.label, d.detail);
208
- else if (isSatisfied(spec, detected)) warn(label, "\uD3F4\uBC31\uC73C\uB85C \uB3D9\uC791 \uC911");
213
+ const base = credLabel(spec);
214
+ const note = credNote(spec);
215
+ const label = note ? `${base} (${note})` : base;
216
+ if (d.present) ok(base, d.detail);
217
+ else if (isSatisfied(spec, detected)) warn(label, t().setup.fallbackWorking);
209
218
  else if (spec.requirement === "optional") warn(`${label}`, `\u2192 ${spec.fix}`);
210
- else fail(spec.label, `\u2192 ${spec.fix}`);
219
+ else fail(base, `\u2192 ${spec.fix}`);
211
220
  }
212
- process.stdout.write(kleur.dim(" \uC804\uBD80 \uC5F0\uACB0\uD558\uAE30: mimi-seed setup \xB7 OAuth \uC2E0\uC120\uB3C4: mimi-seed auth status\n"));
221
+ process.stdout.write(kleur.dim(m.credsHint));
213
222
  const loaded = findProjectManifest(cwd);
214
223
  if (loaded) {
215
- const projName = loaded.manifest.displayName ?? loaded.manifest.project ?? "\uC774 \uD504\uB85C\uC81D\uD2B8";
216
- section(`${projName} \uC694\uAD6C\uC0AC\uD56D (.mimi-seed.json)`);
224
+ const projName = loaded.manifest.displayName ?? loaded.manifest.project ?? m.thisProject;
225
+ section(m.requirements(projName));
217
226
  for (const [id, svc] of manifestServiceEntries(loaded.manifest)) {
218
227
  const required = svc.required !== false;
219
228
  const detail = manifestDetail(id, svc);
220
229
  const spec = tryCredById(id);
221
230
  if (!spec) {
222
- warn(`${id} (\uC54C \uC218 \uC5C6\uB294 \uC11C\uBE44\uC2A4)`, svc.note ?? detail);
231
+ warn(m.unknownService(id), svc.note ?? detail);
223
232
  continue;
224
233
  }
225
234
  const connected = isSatisfied(spec, detected);
226
235
  if (connected) ok(id, detail);
227
- else if (!required) warn(`${id} (\uC120\uD0DD)`, svc.note ?? detail);
236
+ else if (!required) warn(`${id} (${t().common.optional})`, svc.note ?? detail);
228
237
  else fail(id, `\u2192 ${spec.fix}${detail ? " " + detail : ""}`);
229
238
  }
230
239
  }
231
- section("\uB85C\uCEEC \uD658\uACBD");
240
+ section(m.secEnv);
232
241
  const nodeVer = process.version;
233
242
  const [, major] = nodeVer.match(/v(\d+)/) ?? [];
234
243
  if (Number(major) >= 20) {
235
244
  ok("Node.js", nodeVer);
236
245
  } else {
237
- fail("Node.js", `${nodeVer} \u2014 v20 \uC774\uC0C1 \uD544\uC694 (.nvmrc \uCC38\uACE0)`);
246
+ fail("Node.js", m.nodeTooOld(nodeVer));
238
247
  }
239
248
  if (isGitRepo(cwd)) {
240
249
  const latestTag = getLatestTag(cwd);
241
250
  const commits = getGitLog(cwd, { limit: 5 });
242
- ok("Git \uC800\uC7A5\uC18C", latestTag ? `\uCD5C\uC2E0 \uD0DC\uADF8: ${latestTag}` : `\uCEE4\uBC0B ${commits.length}\uAC1C`);
251
+ ok(m.gitRepo, latestTag ? m.gitTag(latestTag) : m.gitCommits(commits.length));
243
252
  } else {
244
- warn("Git \uC800\uC7A5\uC18C \uC5C6\uC74C", "mimi-seed notes \uC0AC\uC6A9 \uBD88\uAC00");
253
+ warn(m.noGit, m.noGitDetail);
245
254
  }
246
- section("\uC571 \uAC10\uC9C0");
255
+ section(m.secApps);
247
256
  const hints = await detectHints(cwd);
248
257
  if (hints.length === 0) {
249
- warn("\uC571 \uAC10\uC9C0 \uC5C6\uC74C", "app.json / build.gradle / Info.plist \uC5C6\uC74C");
258
+ warn(m.noApp, m.noAppDetail);
250
259
  } else {
251
260
  for (const h of hints) {
252
261
  const ids = [h.packageName && `android:${h.packageName}`, h.bundleId && `ios:${h.bundleId}`].filter(Boolean).join(" ");
253
- ok(h.name ?? "(\uC774\uB984 \uBBF8\uC0C1)", ids);
262
+ ok(h.name ?? m.unnamed, ids);
254
263
  }
255
264
  }
256
265
  process.stdout.write("\n");
@@ -732,13 +741,13 @@ ${kleur5.bold("login \uC635\uC158:")}
732
741
  ${kleur5.dim(`\uB0B4\uBD80\uC801\uC73C\uB85C ${MCP_PKG} \uC758 mimi-seed-*-auth CLI\uB97C \uD638\uCD9C\uD569\uB2C8\uB2E4.`)}`);
733
742
  }
734
743
  function printAllCredStatus() {
735
- log(kleur5.bold("\uB85C\uCEEC \uC790\uACA9\uC99D\uBA85 \uC0C1\uD0DC ") + kleur5.dim("(~/.mimi-seed)"));
744
+ log(kleur5.bold(t().auth.statusTitle + " ") + kleur5.dim("(~/.mimi-seed)"));
736
745
  const detected = detectAll();
737
746
  for (const spec of CREDENTIALS) {
738
747
  const d = detected.get(spec.id);
739
748
  const mark = d.present ? kleur5.green("\u2713") : isSatisfied(spec, detected) ? kleur5.yellow("~") : spec.requirement === "optional" ? kleur5.dim("\xB7") : kleur5.red("\u2717");
740
749
  const tail = d.present ? kleur5.dim(d.detail ?? "") : kleur5.dim(`\u2192 ${spec.fix}`);
741
- log(` ${mark} ${spec.label.padEnd(24)} ${tail}`);
750
+ log(` ${mark} ${credLabel(spec).padEnd(24)} ${tail}`);
742
751
  }
743
752
  log(kleur5.dim("\n \uD55C \uBC88\uC5D0 \uC5F0\uACB0: mimi-seed setup"));
744
753
  }
@@ -761,7 +770,7 @@ async function cmdAuth(args) {
761
770
  if (sub === "facebook") return void exitWith(await runMcpBin("mimi-seed-social-auth", ["facebook"]));
762
771
  if (sub === "instagram") return void exitWith(await runMcpBin("mimi-seed-social-auth", ["instagram"]));
763
772
  if (sub === "ci") {
764
- const { cmdSetup: cmdSetup2 } = await import("./setup-ENJIMGJF.js");
773
+ const { cmdSetup: cmdSetup2 } = await import("./setup-G2JY35UW.js");
765
774
  await cmdSetup2(["--only", "github,gitlab", "--reconnect", "github,gitlab"]);
766
775
  return;
767
776
  }
@@ -781,7 +790,7 @@ async function cmdAuth(args) {
781
790
  mcpArgs = ["--logout", ...rest];
782
791
  break;
783
792
  default:
784
- log(kleur5.red(`\uC54C \uC218 \uC5C6\uB294 auth \uC11C\uBE0C\uBA85\uB839: ${sub}`));
793
+ log(kleur5.red(t().auth.unknownSub(sub ?? "")));
785
794
  printAuthHelp();
786
795
  process.exit(1);
787
796
  }
@@ -791,6 +800,33 @@ function exitWith(code) {
791
800
  if (code !== 0) process.exit(code);
792
801
  }
793
802
 
803
+ // src/lang.ts
804
+ import kleur6 from "kleur";
805
+ function log2(msg) {
806
+ process.stdout.write(msg + "\n");
807
+ }
808
+ async function cmdLang(args) {
809
+ const arg = args[0]?.toLowerCase();
810
+ if (!arg) {
811
+ log2(t().lang.current(resolveLang()));
812
+ if (process.env.MIMI_SEED_LANG) {
813
+ log2(kleur6.dim(" (MIMI_SEED_LANG)"));
814
+ }
815
+ return;
816
+ }
817
+ if (arg === "--help" || arg === "-h") {
818
+ log2(t().lang.usage);
819
+ return;
820
+ }
821
+ if (!isLang(arg)) {
822
+ log2(kleur6.red(t().lang.invalid(arg)));
823
+ process.exit(1);
824
+ }
825
+ writeSettings({ lang: arg });
826
+ process.env.MIMI_SEED_LANG = arg;
827
+ log2(kleur6.green(t().lang.saved(arg)));
828
+ }
829
+
794
830
  // src/cloud.ts
795
831
  import { spawn } from "child_process";
796
832
  var MCP_PKG2 = "@yoonion/mimi-seed-mcp";
@@ -827,8 +863,8 @@ import { execSync as execSync2 } from "child_process";
827
863
  import fs2 from "fs";
828
864
  import os from "os";
829
865
  import path2 from "path";
830
- import kleur6 from "kleur";
831
- function log2(msg) {
866
+ import kleur7 from "kleur";
867
+ function log3(msg) {
832
868
  process.stdout.write(msg + "\n");
833
869
  }
834
870
  function readClaudeJson() {
@@ -867,7 +903,7 @@ function killByMarker(marker) {
867
903
  for (const pid of pids) {
868
904
  try {
869
905
  execSync2(`taskkill /F /PID ${pid}`, { stdio: "pipe" });
870
- log2(kleur6.dim(` PID ${pid} \uC885\uB8CC`));
906
+ log3(kleur7.dim(` PID ${pid} \uC885\uB8CC`));
871
907
  killed++;
872
908
  } catch {
873
909
  }
@@ -884,47 +920,47 @@ function killByMarker(marker) {
884
920
  }
885
921
  async function cmdRestart(args) {
886
922
  const serverName = args[0] ?? "mimi-seed";
887
- log2(kleur6.bold(`MCP \uC11C\uBC84 \uC7AC\uC2DC\uC791: ${serverName}`));
888
- log2("");
923
+ log3(kleur7.bold(`MCP \uC11C\uBC84 \uC7AC\uC2DC\uC791: ${serverName}`));
924
+ log3("");
889
925
  const d = readClaudeJson();
890
926
  const servers = d.mcpServers;
891
927
  const cfg = servers?.[serverName];
892
928
  if (!cfg) {
893
929
  const available = servers ? Object.keys(servers).join(", ") : "(\uC5C6\uC74C)";
894
- log2(kleur6.red(`'${serverName}' \uC11C\uBC84\uB97C ~/.claude/.claude.json\uC5D0\uC11C \uCC3E\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4.`));
895
- log2(kleur6.dim(` \uB4F1\uB85D\uB41C \uC11C\uBC84: ${available}`));
930
+ log3(kleur7.red(`'${serverName}' \uC11C\uBC84\uB97C ~/.claude/.claude.json\uC5D0\uC11C \uCC3E\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4.`));
931
+ log3(kleur7.dim(` \uB4F1\uB85D\uB41C \uC11C\uBC84: ${available}`));
896
932
  process.exit(1);
897
933
  }
898
934
  if (cfg.type === "http" || cfg.type === "sse") {
899
- log2(kleur6.yellow(`'${serverName}'\uB294 HTTP/SSE \uC11C\uBC84\uC785\uB2C8\uB2E4. \uD504\uB85C\uC138\uC2A4 \uC7AC\uC2DC\uC791\uC774 \uD544\uC694\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4.`));
900
- log2(kleur6.dim(" Claude Code\uC5D0\uC11C /mcp \uB97C \uC2E4\uD589\uD574 \uC5F0\uACB0 \uC0C1\uD0DC\uB97C \uD655\uC778\uD558\uC138\uC694."));
935
+ log3(kleur7.yellow(`'${serverName}'\uB294 HTTP/SSE \uC11C\uBC84\uC785\uB2C8\uB2E4. \uD504\uB85C\uC138\uC2A4 \uC7AC\uC2DC\uC791\uC774 \uD544\uC694\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4.`));
936
+ log3(kleur7.dim(" Claude Code\uC5D0\uC11C /mcp \uB97C \uC2E4\uD589\uD574 \uC5F0\uACB0 \uC0C1\uD0DC\uB97C \uD655\uC778\uD558\uC138\uC694."));
901
937
  return;
902
938
  }
903
939
  const marker = findProcessMarker(cfg);
904
940
  if (!marker) {
905
- log2(kleur6.yellow("\uD504\uB85C\uC138\uC2A4 \uC2DD\uBCC4\uC790(\uC2A4\uD06C\uB9BD\uD2B8 \uACBD\uB85C)\uB97C \uCC3E\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4."));
906
- log2(kleur6.dim(` \uC124\uC815: ${JSON.stringify(cfg)}`));
941
+ log3(kleur7.yellow("\uD504\uB85C\uC138\uC2A4 \uC2DD\uBCC4\uC790(\uC2A4\uD06C\uB9BD\uD2B8 \uACBD\uB85C)\uB97C \uCC3E\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4."));
942
+ log3(kleur7.dim(` \uC124\uC815: ${JSON.stringify(cfg)}`));
907
943
  process.exit(1);
908
944
  }
909
- log2(kleur6.dim(` \uC2DD\uBCC4\uC790: ${marker}`));
945
+ log3(kleur7.dim(` \uC2DD\uBCC4\uC790: ${marker}`));
910
946
  const { killed } = killByMarker(marker);
911
947
  if (killed === 0) {
912
- log2(kleur6.yellow("\u26A0 \uC2E4\uD589 \uC911\uC778 \uD504\uB85C\uC138\uC2A4\uB97C \uCC3E\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4."));
913
- log2(kleur6.dim(" \uC774\uBBF8 \uC885\uB8CC\uB410\uAC70\uB098, Claude Code\uAC00 \uC544\uC9C1 \uC11C\uBC84\uB97C \uC2DC\uC791\uD558\uC9C0 \uC54A\uC740 \uC0C1\uD0DC\uC77C \uC218 \uC788\uC2B5\uB2C8\uB2E4."));
948
+ log3(kleur7.yellow("\u26A0 \uC2E4\uD589 \uC911\uC778 \uD504\uB85C\uC138\uC2A4\uB97C \uCC3E\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4."));
949
+ log3(kleur7.dim(" \uC774\uBBF8 \uC885\uB8CC\uB410\uAC70\uB098, Claude Code\uAC00 \uC544\uC9C1 \uC11C\uBC84\uB97C \uC2DC\uC791\uD558\uC9C0 \uC54A\uC740 \uC0C1\uD0DC\uC77C \uC218 \uC788\uC2B5\uB2C8\uB2E4."));
914
950
  } else {
915
- log2("");
916
- log2(kleur6.green(`\u2713 ${serverName} \uC885\uB8CC\uB428 (${killed}\uAC1C \uD504\uB85C\uC138\uC2A4)`));
917
- log2(kleur6.dim(" Claude Code\uAC00 \uB2E4\uC74C \uB3C4\uAD6C \uD638\uCD9C \uC2DC \uC790\uB3D9\uC73C\uB85C \uC7AC\uC5F0\uACB0\uD569\uB2C8\uB2E4."));
951
+ log3("");
952
+ log3(kleur7.green(`\u2713 ${serverName} \uC885\uB8CC\uB428 (${killed}\uAC1C \uD504\uB85C\uC138\uC2A4)`));
953
+ log3(kleur7.dim(" Claude Code\uAC00 \uB2E4\uC74C \uB3C4\uAD6C \uD638\uCD9C \uC2DC \uC790\uB3D9\uC73C\uB85C \uC7AC\uC5F0\uACB0\uD569\uB2C8\uB2E4."));
918
954
  }
919
- log2("");
920
- log2(kleur6.cyan(" \uC5F0\uACB0 \uD655\uC778: Claude Code\uC5D0\uC11C /mcp \uC2E4\uD589"));
955
+ log3("");
956
+ log3(kleur7.cyan(" \uC5F0\uACB0 \uD655\uC778: Claude Code\uC5D0\uC11C /mcp \uC2E4\uD589"));
921
957
  }
922
958
 
923
959
  // src/mcp-config.ts
924
960
  import fs3 from "fs/promises";
925
961
  import path3 from "path";
926
962
  import os2 from "os";
927
- import kleur7 from "kleur";
963
+ import kleur8 from "kleur";
928
964
  var SERVER_NAME = "mimi-seed";
929
965
  function tomlString(value) {
930
966
  return JSON.stringify(value);
@@ -956,13 +992,13 @@ function claudeMcpAddCommand(cfg) {
956
992
  function printMcpSetup(cfg) {
957
993
  process.stdout.write(
958
994
  [
959
- kleur7.bold("Claude Code MCP \uB4F1\uB85D \u2014 \uC544\uB798 \uD55C \uC904\uC744 \uADF8\uB300\uB85C \uC2E4\uD589\uD558\uC138\uC694:"),
960
- kleur7.cyan(` ${claudeMcpAddCommand(cfg)}`),
961
- kleur7.dim(` \u26A0 \uC2E4\uC81C \uD1A0\uD070\uC774 \uD3EC\uD568\uB41C \uBA85\uB839\uC785\uB2C8\uB2E4 (\uC178 \uD788\uC2A4\uD1A0\uB9AC\uC5D0 \uB0A8\uC74C). \uD1A0\uD070\uC740 ${CONFIG_LOCATION_HINT} \uC5D0\uB3C4 \uC800\uC7A5\uB418\uC5B4 \uC788\uC2B5\uB2C8\uB2E4.`),
995
+ kleur8.bold("Claude Code MCP \uB4F1\uB85D \u2014 \uC544\uB798 \uD55C \uC904\uC744 \uADF8\uB300\uB85C \uC2E4\uD589\uD558\uC138\uC694:"),
996
+ kleur8.cyan(` ${claudeMcpAddCommand(cfg)}`),
997
+ kleur8.dim(` \u26A0 \uC2E4\uC81C \uD1A0\uD070\uC774 \uD3EC\uD568\uB41C \uBA85\uB839\uC785\uB2C8\uB2E4 (\uC178 \uD788\uC2A4\uD1A0\uB9AC\uC5D0 \uB0A8\uC74C). \uD1A0\uD070\uC740 ${CONFIG_LOCATION_HINT} \uC5D0\uB3C4 \uC800\uC7A5\uB418\uC5B4 \uC788\uC2B5\uB2C8\uB2E4.`),
962
998
  "",
963
- kleur7.dim("Codex MCP \uB4F1\uB85D:"),
964
- kleur7.dim(" mimi-seed mcp codex --write"),
965
- kleur7.dim(" # \uB610\uB294 \uC218\uB3D9\uC73C\uB85C ~/.codex/config.toml \uC5D0 [mcp_servers.mimi-seed] \uCD94\uAC00")
999
+ kleur8.dim("Codex MCP \uB4F1\uB85D:"),
1000
+ kleur8.dim(" mimi-seed mcp codex --write"),
1001
+ kleur8.dim(" # \uB610\uB294 \uC218\uB3D9\uC73C\uB85C ~/.codex/config.toml \uC5D0 [mcp_servers.mimi-seed] \uCD94\uAC00")
966
1002
  ].join("\n") + "\n"
967
1003
  );
968
1004
  }
@@ -1027,62 +1063,62 @@ async function ensureReleaseManifest(cwd) {
1027
1063
  // src/index.ts
1028
1064
  var DEFAULT_WEB_BASE = process.env.MIMI_SEED_WEB_BASE ?? "https://mimi-seed.pryzm.gg";
1029
1065
  var DEFAULT_MCP_ENDPOINT = `${DEFAULT_WEB_BASE}/api/mcp`;
1030
- function log3(msg) {
1066
+ function log4(msg) {
1031
1067
  process.stdout.write(msg + "\n");
1032
1068
  }
1033
1069
  async function cmdInit(args) {
1034
1070
  const local = args.includes("--local");
1035
1071
  const cwd = process.cwd();
1036
- log3(kleur8.bold("Mimi Seed CLI \u2014 init"));
1037
- log3(kleur8.dim(cwd));
1038
- log3("");
1072
+ log4(kleur9.bold("Mimi Seed CLI \u2014 init"));
1073
+ log4(kleur9.dim(cwd));
1074
+ log4("");
1039
1075
  if (!await hasAnyProjectSignal(cwd)) {
1040
- log3(kleur8.yellow("\u26A0 package.json / app.json / android / ios \uB97C \uCC3E\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4. \uADF8\uB798\uB3C4 \uC9C4\uD589\uD569\uB2C8\uB2E4."));
1076
+ log4(kleur9.yellow("\u26A0 package.json / app.json / android / ios \uB97C \uCC3E\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4. \uADF8\uB798\uB3C4 \uC9C4\uD589\uD569\uB2C8\uB2E4."));
1041
1077
  }
1042
- log3("\u{1F50D} \uC571 \uAC10\uC9C0 \uC911...");
1078
+ log4("\u{1F50D} \uC571 \uAC10\uC9C0 \uC911...");
1043
1079
  const hints = await detectHints(cwd);
1044
1080
  if (hints.length === 0) {
1045
- log3(kleur8.yellow("\uAC10\uC9C0\uB41C \uC571 \uC5C6\uC74C. \uC6F9\uC5D0\uC11C \uC218\uB3D9 \uB4F1\uB85D \uAC00\uB2A5."));
1081
+ log4(kleur9.yellow("\uAC10\uC9C0\uB41C \uC571 \uC5C6\uC74C. \uC6F9\uC5D0\uC11C \uC218\uB3D9 \uB4F1\uB85D \uAC00\uB2A5."));
1046
1082
  } else {
1047
1083
  for (const h of hints) {
1048
1084
  const tag = [h.packageName && `android:${h.packageName}`, h.bundleId && `ios:${h.bundleId}`].filter(Boolean).join(" ");
1049
- log3(` \u2022 ${h.name ?? "(\uC774\uB984 \uBBF8\uC0C1)"} ${kleur8.dim(tag)}`);
1085
+ log4(` \u2022 ${h.name ?? "(\uC774\uB984 \uBBF8\uC0C1)"} ${kleur9.dim(tag)}`);
1050
1086
  }
1051
1087
  }
1052
- log3("");
1088
+ log4("");
1053
1089
  if (process.env.MIMI_SEED_TOKEN) {
1054
1090
  const cfg2 = await getEffectiveConfig();
1055
1091
  if (cfg2 && hints.length > 0) {
1056
- log3(kleur8.dim("CI \uBAA8\uB4DC: MIMI_SEED_TOKEN \uC0AC\uC6A9"));
1092
+ log4(kleur9.dim("CI \uBAA8\uB4DC: MIMI_SEED_TOKEN \uC0AC\uC6A9"));
1057
1093
  const payload = hints.map((h) => ({ name: h.name, packageName: h.packageName, bundleId: h.bundleId }));
1058
1094
  const result = await mcpCall(cfg2.endpoint, cfg2.token, "sync_apps", { hints: payload });
1059
1095
  if (result.isError) {
1060
- log3(kleur8.red("\uB4F1\uB85D \uC2E4\uD328: " + result.text));
1096
+ log4(kleur9.red("\uB4F1\uB85D \uC2E4\uD328: " + result.text));
1061
1097
  } else {
1062
- for (const line of result.text.split("\n")) log3(" " + line);
1098
+ for (const line of result.text.split("\n")) log4(" " + line);
1063
1099
  }
1064
1100
  }
1065
1101
  const manifest2 = await ensureReleaseManifest(cwd);
1066
- log3(kleur8.dim(` \uB9B4\uB9AC\uC988 \uB178\uD2B8 SSOT: ${manifest2.created ? "\uC0DD\uC131" : "\uD655\uC778"} docs/releases.json`));
1067
- log3(kleur8.bold("\u2713 \uC644\uB8CC (CI \uBAA8\uB4DC)"));
1102
+ log4(kleur9.dim(` \uB9B4\uB9AC\uC988 \uB178\uD2B8 SSOT: ${manifest2.created ? "\uC0DD\uC131" : "\uD655\uC778"} docs/releases.json`));
1103
+ log4(kleur9.bold("\u2713 \uC644\uB8CC (CI \uBAA8\uB4DC)"));
1068
1104
  return;
1069
1105
  }
1070
- log3("\u{1F510} \uBE0C\uB77C\uC6B0\uC800\uC5D0\uC11C \uB85C\uADF8\uC778 \uB300\uAE30...");
1106
+ log4("\u{1F510} \uBE0C\uB77C\uC6B0\uC800\uC5D0\uC11C \uB85C\uADF8\uC778 \uB300\uAE30...");
1071
1107
  const hostName = os3.hostname().slice(0, 32);
1072
1108
  const name = `cli-${hostName}`;
1073
1109
  const { port, promise } = await awaitHandshake(5 * 60 * 1e3);
1074
1110
  const callback = `http://127.0.0.1:${port}/cb`;
1075
1111
  const connectUrl = `${DEFAULT_WEB_BASE}/cli/connect?callback=${encodeURIComponent(callback)}&name=${encodeURIComponent(name)}`;
1076
- log3(kleur8.dim(` ${connectUrl}`));
1112
+ log4(kleur9.dim(` ${connectUrl}`));
1077
1113
  await open(connectUrl);
1078
1114
  let handshake;
1079
1115
  try {
1080
1116
  handshake = await promise;
1081
1117
  } catch (e) {
1082
- log3(kleur8.red("\uC5F0\uACB0 \uC2E4\uD328: " + e.message));
1118
+ log4(kleur9.red("\uC5F0\uACB0 \uC2E4\uD328: " + e.message));
1083
1119
  process.exit(1);
1084
1120
  }
1085
- log3(kleur8.green("\u2713 \uD1A0\uD070 \uC218\uC2E0"));
1121
+ log4(kleur9.green("\u2713 \uD1A0\uD070 \uC218\uC2E0"));
1086
1122
  const cfg = {
1087
1123
  token: handshake.token,
1088
1124
  prefix: handshake.prefix,
@@ -1091,18 +1127,18 @@ async function cmdInit(args) {
1091
1127
  createdAt: (/* @__PURE__ */ new Date()).toISOString()
1092
1128
  };
1093
1129
  await writeConfig(cfg);
1094
- log3(kleur8.dim(` \uC800\uC7A5\uB428: ${CONFIG_LOCATION}`));
1095
- log3("");
1130
+ log4(kleur9.dim(` \uC800\uC7A5\uB428: ${CONFIG_LOCATION}`));
1131
+ log4("");
1096
1132
  if (hints.length > 0) {
1097
- log3("\u{1F504} \uC571 \uB4F1\uB85D \uC911...");
1133
+ log4("\u{1F504} \uC571 \uB4F1\uB85D \uC911...");
1098
1134
  const payload = hints.map((h) => ({ name: h.name, packageName: h.packageName, bundleId: h.bundleId }));
1099
1135
  const result = await mcpCall(cfg.endpoint, cfg.token, "sync_apps", { hints: payload });
1100
1136
  if (result.isError) {
1101
- log3(kleur8.red("\uB4F1\uB85D \uC2E4\uD328: " + result.text));
1137
+ log4(kleur9.red("\uB4F1\uB85D \uC2E4\uD328: " + result.text));
1102
1138
  } else {
1103
- for (const line of result.text.split("\n")) log3(" " + line);
1139
+ for (const line of result.text.split("\n")) log4(" " + line);
1104
1140
  }
1105
- log3("");
1141
+ log4("");
1106
1142
  }
1107
1143
  const appLines = hints.flatMap((h) => {
1108
1144
  const parts = [
@@ -1151,111 +1187,111 @@ async function cmdInit(args) {
1151
1187
  if (!fs5.existsSync(claudeAgentPath)) {
1152
1188
  fs5.mkdirSync(claudeDir, { recursive: true });
1153
1189
  fs5.writeFileSync(claudeAgentPath, agentMd, { mode: 420 });
1154
- log3(kleur8.dim(` Claude \uC5D0\uC774\uC804\uD2B8 \uC124\uC815: .claude/mimi-seed.md`));
1190
+ log4(kleur9.dim(` Claude \uC5D0\uC774\uC804\uD2B8 \uC124\uC815: .claude/mimi-seed.md`));
1155
1191
  }
1156
1192
  const codexAgentPath = path5.join(cwd, "AGENTS.md");
1157
1193
  if (!fs5.existsSync(codexAgentPath)) {
1158
1194
  fs5.writeFileSync(codexAgentPath, agentMd, { mode: 420 });
1159
- log3(kleur8.dim(` Codex \uC5D0\uC774\uC804\uD2B8 \uC124\uC815: AGENTS.md`));
1195
+ log4(kleur9.dim(` Codex \uC5D0\uC774\uC804\uD2B8 \uC124\uC815: AGENTS.md`));
1160
1196
  }
1161
1197
  const manifest = await ensureReleaseManifest(cwd);
1162
- log3(kleur8.dim(` \uB9B4\uB9AC\uC988 \uB178\uD2B8 SSOT: ${manifest.created ? "\uC0DD\uC131" : "\uD655\uC778"} docs/releases.json`));
1163
- log3(kleur8.bold("\u2713 \uC900\uBE44 \uC644\uB8CC."));
1164
- log3("");
1165
- log3("Claude Code \uB610\uB294 Codex\uC5D0\uC11C \uC774\uB807\uAC8C \uBB3C\uC5B4\uBCF4\uC138\uC694:");
1166
- log3(kleur8.cyan(' "\uB0B4 \uC571 \uCD9C\uC2DC \uC900\uBE44\uB410\uC5B4?"'));
1167
- log3(kleur8.cyan(' "\uB9B4\uB9AC\uC988 \uB178\uD2B8 \uC368\uC918"'));
1168
- log3(kleur8.cyan(' "\uB4F1\uB85D\uB41C \uC571 \uBAA9\uB85D \uBCF4\uC5EC\uC918"'));
1169
- log3("");
1170
- log3(`\uB300\uC2DC\uBCF4\uB4DC: ${kleur8.underline(DEFAULT_WEB_BASE + "/apps")}`);
1171
- log3("");
1198
+ log4(kleur9.dim(` \uB9B4\uB9AC\uC988 \uB178\uD2B8 SSOT: ${manifest.created ? "\uC0DD\uC131" : "\uD655\uC778"} docs/releases.json`));
1199
+ log4(kleur9.bold("\u2713 \uC900\uBE44 \uC644\uB8CC."));
1200
+ log4("");
1201
+ log4("Claude Code \uB610\uB294 Codex\uC5D0\uC11C \uC774\uB807\uAC8C \uBB3C\uC5B4\uBCF4\uC138\uC694:");
1202
+ log4(kleur9.cyan(' "\uB0B4 \uC571 \uCD9C\uC2DC \uC900\uBE44\uB410\uC5B4?"'));
1203
+ log4(kleur9.cyan(' "\uB9B4\uB9AC\uC988 \uB178\uD2B8 \uC368\uC918"'));
1204
+ log4(kleur9.cyan(' "\uB4F1\uB85D\uB41C \uC571 \uBAA9\uB85D \uBCF4\uC5EC\uC918"'));
1205
+ log4("");
1206
+ log4(`\uB300\uC2DC\uBCF4\uB4DC: ${kleur9.underline(DEFAULT_WEB_BASE + "/apps")}`);
1207
+ log4("");
1172
1208
  printMcpSetup(cfg);
1173
1209
  if (local) {
1174
- log3("");
1175
- log3(kleur8.bold("\u2500\u2500 \uB85C\uCEEC MCP \uCD94\uAC00 \uC124\uC815 (--local) \u2500\u2500"));
1176
- log3(kleur8.dim("\uC6D0\uACA9 MCP(PAT, \uC77D\uAE30\xB7\uC9C4\uB2E8)\uB294 \uC704\uC5D0\uC11C \uB05D. \uB85C\uCEEC MCP\uB294 Google OAuth\uB85C \uC2A4\uD1A0\uC5B4 \uC4F0\uAE30 \uB3C4\uAD6C \uC804\uCCB4\uB97C \uC9C1\uC811 \uC2E4\uD589\uD569\uB2C8\uB2E4 (Node 20+)."));
1177
- log3("");
1178
- log3("1) Google \uB85C\uADF8\uC778 (Firebase / AdMob / Play / Ads):");
1210
+ log4("");
1211
+ log4(kleur9.bold("\u2500\u2500 \uB85C\uCEEC MCP \uCD94\uAC00 \uC124\uC815 (--local) \u2500\u2500"));
1212
+ log4(kleur9.dim("\uC6D0\uACA9 MCP(PAT, \uC77D\uAE30\xB7\uC9C4\uB2E8)\uB294 \uC704\uC5D0\uC11C \uB05D. \uB85C\uCEEC MCP\uB294 Google OAuth\uB85C \uC2A4\uD1A0\uC5B4 \uC4F0\uAE30 \uB3C4\uAD6C \uC804\uCCB4\uB97C \uC9C1\uC811 \uC2E4\uD589\uD569\uB2C8\uB2E4 (Node 20+)."));
1213
+ log4("");
1214
+ log4("1) Google \uB85C\uADF8\uC778 (Firebase / AdMob / Play / Ads):");
1179
1215
  await cmdAuth(["login"]);
1180
- log3("");
1181
- log3("2) \uB85C\uCEEC MCP \uC11C\uBC84 \uB4F1\uB85D (\uC6D0\uACA9 'mimi-seed' \uC640 \uBCC4\uAC1C):");
1182
- log3(kleur8.cyan(" claude mcp add mimi-seed-local -- npx -y @yoonion/mimi-seed-mcp"));
1183
- log3(kleur8.dim(' Codex: ~/.codex/config.toml \uC5D0 [mcp_servers.mimi-seed-local] command="npx", args=["-y","@yoonion/mimi-seed-mcp"]'));
1184
- log3("");
1185
- log3("3) \uB098\uBA38\uC9C0 \uACC4\uC815 \uC5F0\uACB0 (App Store / Play / Jenkins / CI / \uC18C\uC15C \u2026):");
1186
- log3(kleur8.cyan(" mimi-seed setup"));
1187
- log3(kleur8.dim(" \uAC01 \uD56D\uBAA9\uC5D0\uC11C [?] \uB97C \uB204\uB974\uBA74 \uD1A0\uD070 \uBC1C\uAE09 \uBC29\uBC95\uC744 \uC54C\uB824\uC90D\uB2C8\uB2E4."));
1216
+ log4("");
1217
+ log4("2) \uB85C\uCEEC MCP \uC11C\uBC84 \uB4F1\uB85D (\uC6D0\uACA9 'mimi-seed' \uC640 \uBCC4\uAC1C):");
1218
+ log4(kleur9.cyan(" claude mcp add mimi-seed-local -- npx -y @yoonion/mimi-seed-mcp"));
1219
+ log4(kleur9.dim(' Codex: ~/.codex/config.toml \uC5D0 [mcp_servers.mimi-seed-local] command="npx", args=["-y","@yoonion/mimi-seed-mcp"]'));
1220
+ log4("");
1221
+ log4("3) \uB098\uBA38\uC9C0 \uACC4\uC815 \uC5F0\uACB0 (App Store / Play / Jenkins / CI / \uC18C\uC15C \u2026):");
1222
+ log4(kleur9.cyan(" mimi-seed setup"));
1223
+ log4(kleur9.dim(" \uAC01 \uD56D\uBAA9\uC5D0\uC11C [?] \uB97C \uB204\uB974\uBA74 \uD1A0\uD070 \uBC1C\uAE09 \uBC29\uBC95\uC744 \uC54C\uB824\uC90D\uB2C8\uB2E4."));
1188
1224
  }
1189
1225
  }
1190
1226
  async function cmdStatus() {
1191
1227
  const cfg = await getEffectiveConfig();
1192
1228
  if (!cfg) {
1193
- log3(kleur8.yellow("\uC5F0\uACB0\uB41C Mimi Seed \uACC4\uC815\uC774 \uC5C6\uC2B5\uB2C8\uB2E4. `mimi-seed init` \uC2E4\uD589."));
1229
+ log4(kleur9.yellow("\uC5F0\uACB0\uB41C Mimi Seed \uACC4\uC815\uC774 \uC5C6\uC2B5\uB2C8\uB2E4. `mimi-seed init` \uC2E4\uD589."));
1194
1230
  process.exit(1);
1195
1231
  }
1196
- log3(kleur8.bold("Mimi Seed \uC5F0\uACB0 \uC0C1\uD0DC"));
1197
- log3(` \uD1A0\uD070: ${cfg.prefix}\u2026 (${cfg.createdAt.slice(0, 10)})`);
1198
- log3(` \uC5D4\uB4DC\uD3EC\uC778\uD2B8: ${cfg.endpoint}`);
1199
- log3("");
1200
- log3("\u{1F4CB} \uC571 \uBAA9\uB85D:");
1232
+ log4(kleur9.bold("Mimi Seed \uC5F0\uACB0 \uC0C1\uD0DC"));
1233
+ log4(` \uD1A0\uD070: ${cfg.prefix}\u2026 (${cfg.createdAt.slice(0, 10)})`);
1234
+ log4(` \uC5D4\uB4DC\uD3EC\uC778\uD2B8: ${cfg.endpoint}`);
1235
+ log4("");
1236
+ log4("\u{1F4CB} \uC571 \uBAA9\uB85D:");
1201
1237
  const r = await mcpCall(cfg.endpoint, cfg.token, "list_apps", {});
1202
1238
  if (r.isError) {
1203
- log3(kleur8.red("\uC870\uD68C \uC2E4\uD328: " + r.text));
1239
+ log4(kleur9.red("\uC870\uD68C \uC2E4\uD328: " + r.text));
1204
1240
  process.exit(1);
1205
1241
  }
1206
- for (const line of r.text.split("\n")) log3(" " + line);
1242
+ for (const line of r.text.split("\n")) log4(" " + line);
1207
1243
  }
1208
1244
  async function cmdLogout() {
1209
1245
  await deleteConfig();
1210
- log3(kleur8.green("\u2713 \uB85C\uCEEC \uC124\uC815 \uC0AD\uC81C \uC644\uB8CC."));
1211
- log3(kleur8.dim("\uC6F9\uC5D0\uC11C \uD1A0\uD070 \uD574\uC9C0: /workspace/api-tokens"));
1246
+ log4(kleur9.green("\u2713 \uB85C\uCEEC \uC124\uC815 \uC0AD\uC81C \uC644\uB8CC."));
1247
+ log4(kleur9.dim("\uC6F9\uC5D0\uC11C \uD1A0\uD070 \uD574\uC9C0: /workspace/api-tokens"));
1212
1248
  }
1213
1249
  async function cmdMcp(args) {
1214
1250
  const target = args[0] ?? "help";
1215
1251
  const cfg = await getEffectiveConfig();
1216
1252
  if (!cfg) {
1217
- log3(kleur8.yellow("\uC5F0\uACB0\uB41C Mimi Seed \uACC4\uC815\uC774 \uC5C6\uC2B5\uB2C8\uB2E4. `mimi-seed init` \uC2E4\uD589."));
1253
+ log4(kleur9.yellow("\uC5F0\uACB0\uB41C Mimi Seed \uACC4\uC815\uC774 \uC5C6\uC2B5\uB2C8\uB2E4. `mimi-seed init` \uC2E4\uD589."));
1218
1254
  process.exit(1);
1219
1255
  }
1220
1256
  if (target === "codex") {
1221
1257
  if (args.includes("--write")) {
1222
1258
  const configPath = await writeCodexMcpConfig(cfg);
1223
- log3(kleur8.green("\u2713 Codex MCP \uC124\uC815 \uC644\uB8CC"));
1224
- log3(kleur8.dim(` ${configPath}`));
1225
- log3(kleur8.dim(" \u26A0 config.toml\uC5D0 \uC2E4\uC81C \uD1A0\uD070\uC774 \uD3C9\uBB38\uC73C\uB85C \uC800\uC7A5\uB429\uB2C8\uB2E4 (\uD30C\uC77C \uAD8C\uD55C \uD655\uC778 \uAD8C\uC7A5)."));
1226
- log3("");
1227
- log3("Codex\uB97C \uC0C8\uB85C \uC5F4\uACE0 `/mcp` \uB610\uB294 `codex mcp list`\uB85C \uD655\uC778\uD558\uC138\uC694.");
1259
+ log4(kleur9.green("\u2713 Codex MCP \uC124\uC815 \uC644\uB8CC"));
1260
+ log4(kleur9.dim(` ${configPath}`));
1261
+ log4(kleur9.dim(" \u26A0 config.toml\uC5D0 \uC2E4\uC81C \uD1A0\uD070\uC774 \uD3C9\uBB38\uC73C\uB85C \uC800\uC7A5\uB429\uB2C8\uB2E4 (\uD30C\uC77C \uAD8C\uD55C \uD655\uC778 \uAD8C\uC7A5)."));
1262
+ log4("");
1263
+ log4("Codex\uB97C \uC0C8\uB85C \uC5F4\uACE0 `/mcp` \uB610\uB294 `codex mcp list`\uB85C \uD655\uC778\uD558\uC138\uC694.");
1228
1264
  return;
1229
1265
  }
1230
- log3(kleur8.bold("Codex MCP \uB4F1\uB85D"));
1231
- log3("");
1232
- log3("\uC790\uB3D9 \uB4F1\uB85D:");
1233
- log3(kleur8.cyan(" mimi-seed mcp codex --write"));
1234
- log3("");
1235
- log3("\uC218\uB3D9 \uB4F1\uB85D \uC608\uC2DC (~/.codex/config.toml) \u2014 \uC2E4\uC81C \uD1A0\uD070 \uD3EC\uD568:");
1236
- log3(`[mcp_servers.mimi-seed]
1266
+ log4(kleur9.bold("Codex MCP \uB4F1\uB85D"));
1267
+ log4("");
1268
+ log4("\uC790\uB3D9 \uB4F1\uB85D:");
1269
+ log4(kleur9.cyan(" mimi-seed mcp codex --write"));
1270
+ log4("");
1271
+ log4("\uC218\uB3D9 \uB4F1\uB85D \uC608\uC2DC (~/.codex/config.toml) \u2014 \uC2E4\uC81C \uD1A0\uD070 \uD3EC\uD568:");
1272
+ log4(`[mcp_servers.mimi-seed]
1237
1273
  url = "${cfg.endpoint}"
1238
1274
  enabled = true
1239
1275
  http_headers = { Authorization = "Bearer ${cfg.token}" }`);
1240
1276
  return;
1241
1277
  }
1242
1278
  if (target === "claude") {
1243
- log3(kleur8.bold("Claude Code MCP \uB4F1\uB85D \u2014 \uC544\uB798 \uD55C \uC904\uC744 \uADF8\uB300\uB85C \uC2E4\uD589\uD558\uC138\uC694:"));
1244
- log3(kleur8.cyan(` ${claudeMcpAddCommand(cfg)}`));
1245
- log3(kleur8.dim(" \u26A0 \uC2E4\uC81C \uD1A0\uD070\uC774 \uD3EC\uD568\uB41C \uBA85\uB839\uC785\uB2C8\uB2E4 (\uC178 \uD788\uC2A4\uD1A0\uB9AC\uC5D0 \uB0A8\uC74C). \uD1A0\uD070\uC740 ~/.mimi-seed/config.json \uC5D0\uB3C4 \uC800\uC7A5\uB418\uC5B4 \uC788\uC2B5\uB2C8\uB2E4."));
1279
+ log4(kleur9.bold("Claude Code MCP \uB4F1\uB85D \u2014 \uC544\uB798 \uD55C \uC904\uC744 \uADF8\uB300\uB85C \uC2E4\uD589\uD558\uC138\uC694:"));
1280
+ log4(kleur9.cyan(` ${claudeMcpAddCommand(cfg)}`));
1281
+ log4(kleur9.dim(" \u26A0 \uC2E4\uC81C \uD1A0\uD070\uC774 \uD3EC\uD568\uB41C \uBA85\uB839\uC785\uB2C8\uB2E4 (\uC178 \uD788\uC2A4\uD1A0\uB9AC\uC5D0 \uB0A8\uC74C). \uD1A0\uD070\uC740 ~/.mimi-seed/config.json \uC5D0\uB3C4 \uC800\uC7A5\uB418\uC5B4 \uC788\uC2B5\uB2C8\uB2E4."));
1246
1282
  return;
1247
1283
  }
1248
1284
  printMcpSetup(cfg);
1249
1285
  }
1250
1286
  var CMD_USAGE = {
1251
- init: `${kleur8.bold("mimi-seed init")} \u2014 \uD604\uC7AC \uD504\uB85C\uC81D\uD2B8\uB97C Mimi Seed\uC5D0 \uC5F0\uACB0
1287
+ init: `${kleur9.bold("mimi-seed init")} \u2014 \uD604\uC7AC \uD504\uB85C\uC81D\uD2B8\uB97C Mimi Seed\uC5D0 \uC5F0\uACB0
1252
1288
 
1253
1289
  \uC571 \uC790\uB3D9 \uAC10\uC9C0(Expo/Gradle/Info.plist/pbxproj) \u2192 \uBE0C\uB77C\uC6B0\uC800 PAT \uBC1C\uAE09(\uC6D0\uACA9 MCP) \u2192 \uC571 \uB4F1\uB85D
1254
1290
  + .claude/mimi-seed.md, AGENTS.md, docs/releases.json \uC0DD\uC131/\uD655\uC778.
1255
1291
 
1256
1292
  \uC635\uC158:
1257
1293
  --local \uCD94\uAC00\uB85C Google OAuth \uB85C\uADF8\uC778 + \uB85C\uCEEC MCP(\uC2A4\uD1A0\uC5B4 \uC4F0\uAE30 \uB3C4\uAD6C \uC804\uCCB4) \uB4F1\uB85D \uC548\uB0B4`,
1258
- setup: `${kleur8.bold("mimi-seed setup")} \u2014 \uAC00\uC9C4 \uACC4\uC815\uC744 \uD55C \uBC88\uC5D0 \uC5F0\uACB0 (\uC548\uB0B4\uD615 \uB9C8\uBC95\uC0AC)
1294
+ setup: `${kleur9.bold("mimi-seed setup")} \u2014 \uAC00\uC9C4 \uACC4\uC815\uC744 \uD55C \uBC88\uC5D0 \uC5F0\uACB0 (\uC548\uB0B4\uD615 \uB9C8\uBC95\uC0AC)
1259
1295
 
1260
1296
  \uC5F0\uACB0 \uC0C1\uD0DC\uB97C \uBA3C\uC800 \uBCF4\uC5EC\uC8FC\uACE0, \uC544\uC9C1 \uC5F0\uACB0\uB418\uC9C0 \uC54A\uC740 \uAC83\uB9CC \uC21C\uC11C\uB300\uB85C \uBB3C\uC5B4\uBCF8\uB2E4.
1261
1297
  \uAC01 \uD56D\uBAA9\uC5D0\uC11C [?] \uB97C \uB204\uB974\uBA74 "\uADF8 \uD1A0\uD070\uC744 \uC5B4\uB514\uC11C \uC5B4\uB5BB\uAC8C \uBC1C\uAE09\uBC1B\uB294\uC9C0"\uB97C \uC54C\uB824\uC900\uB2E4.
@@ -1269,14 +1305,22 @@ var CMD_USAGE = {
1269
1305
  --non-interactive \uC704\uC640 \uB3D9\uC77C (CI \uC6A9)
1270
1306
  --fail-on-missing \uD544\uC218 \uC790\uACA9\uC99D\uBA85\uC774 \uC5C6\uC73C\uBA74 exit 1 (CI \uAC8C\uC774\uD2B8)
1271
1307
 
1272
- ${kleur8.dim("\uBE44TTY / CI \uD658\uACBD\uC5D0\uC11C\uB294 \uD504\uB86C\uD504\uD2B8 \uC5C6\uC774 \uC0C1\uD0DC\uD45C\uB9CC \uCD9C\uB825\uD55C\uB2E4.")}`,
1273
- status: `${kleur8.bold("mimi-seed status")} \u2014 \uC5F0\uACB0 \uC0C1\uD0DC + \uB4F1\uB85D \uC571 \uBAA9\uB85D. \uC635\uC158 \uC5C6\uC74C.`,
1274
- doctor: `${kleur8.bold("mimi-seed doctor")} \u2014 \uD658\uACBD \uC9C4\uB2E8 (\uD1A0\uD070\xB7Node\xB7Git\xB7\uD504\uB85C\uC81D\uD2B8\xB7CI). \uC635\uC158 \uC5C6\uC74C.`,
1275
- logout: `${kleur8.bold("mimi-seed logout")} \u2014 \uB85C\uCEEC \uC124\uC815(config.json) \uC0AD\uC81C. \uC635\uC158 \uC5C6\uC74C.`,
1276
- restart: `${kleur8.bold("mimi-seed restart")} \u2014 MCP \uC11C\uBC84 \uD504\uB85C\uC138\uC2A4 \uC7AC\uC2DC\uC791 (\uAE30\uBCF8: mimi-seed)
1308
+ ${kleur9.dim("\uBE44TTY / CI \uD658\uACBD\uC5D0\uC11C\uB294 \uD504\uB86C\uD504\uD2B8 \uC5C6\uC774 \uC0C1\uD0DC\uD45C\uB9CC \uCD9C\uB825\uD55C\uB2E4.")}`,
1309
+ lang: `${kleur9.bold("mimi-seed lang")} \u2014 CLI \uCD9C\uB825 \uC5B8\uC5B4 (\uD55C\uAD6D\uC5B4 / English)
1310
+
1311
+ mimi-seed lang \uD604\uC7AC \uC5B8\uC5B4 \uD45C\uC2DC
1312
+ mimi-seed lang ko \uD55C\uAD6D\uC5B4 (\uAE30\uBCF8)
1313
+ mimi-seed lang en English
1314
+
1315
+ ${kleur9.dim("~/.mimi-seed/settings.json \uC5D0 \uC800\uC7A5\uB429\uB2C8\uB2E4. \uD658\uACBD\uBCC0\uC218 MIMI_SEED_LANG \uAC00 \uC788\uC73C\uBA74 \uADF8\uAC8C \uC6B0\uC120\uD569\uB2C8\uB2E4.")}
1316
+ ${kleur9.dim("setup \uB9C8\uBC95\uC0AC\uAC00 \uCCAB \uC2E4\uD589 \uB54C \uBB3C\uC5B4\uBCF4\uBBC0\uB85C \uBCF4\uD1B5\uC740 \uC9C1\uC811 \uCE60 \uC77C\uC774 \uC5C6\uC2B5\uB2C8\uB2E4.")}`,
1317
+ status: `${kleur9.bold("mimi-seed status")} \u2014 \uC5F0\uACB0 \uC0C1\uD0DC + \uB4F1\uB85D \uC571 \uBAA9\uB85D. \uC635\uC158 \uC5C6\uC74C.`,
1318
+ doctor: `${kleur9.bold("mimi-seed doctor")} \u2014 \uD658\uACBD \uC9C4\uB2E8 (\uD1A0\uD070\xB7Node\xB7Git\xB7\uD504\uB85C\uC81D\uD2B8\xB7CI). \uC635\uC158 \uC5C6\uC74C.`,
1319
+ logout: `${kleur9.bold("mimi-seed logout")} \u2014 \uB85C\uCEEC \uC124\uC815(config.json) \uC0AD\uC81C. \uC635\uC158 \uC5C6\uC74C.`,
1320
+ restart: `${kleur9.bold("mimi-seed restart")} \u2014 MCP \uC11C\uBC84 \uD504\uB85C\uC138\uC2A4 \uC7AC\uC2DC\uC791 (\uAE30\uBCF8: mimi-seed)
1277
1321
 
1278
1322
  mimi-seed restart [server-name]`,
1279
- notes: `${kleur8.bold("mimi-seed notes")} \u2014 \uB9B4\uB9AC\uC988 \uB178\uD2B8 \uC0DD\uC131 (git log \u2192 AI \u2192 \uB9C8\uCF13 \uC801\uC6A9)
1323
+ notes: `${kleur9.bold("mimi-seed notes")} \u2014 \uB9B4\uB9AC\uC988 \uB178\uD2B8 \uC0DD\uC131 (git log \u2192 AI \u2192 \uB9C8\uCF13 \uC801\uC6A9)
1280
1324
 
1281
1325
  \uC635\uC158:
1282
1326
  --from <ref> \uC2DC\uC791 \uCEE4\uBC0B/\uD0DC\uADF8 (\uAE30\uBCF8: \uCD5C\uC2E0 \uD0DC\uADF8)
@@ -1285,12 +1329,12 @@ ${kleur8.dim("\uBE44TTY / CI \uD658\uACBD\uC5D0\uC11C\uB294 \uD504\uB86C\uD504\u
1285
1329
  --apply \uC0DD\uC131 \uD6C4 \uC2A4\uD1A0\uC5B4\uC5D0 \uBC14\uB85C \uC801\uC6A9
1286
1330
  --no-interactive CI \uBAA8\uB4DC (\uD504\uB86C\uD504\uD2B8 \uC5C6\uC74C)
1287
1331
  --limit <n> \uCD5C\uB300 \uCEE4\uBC0B \uC218 (\uAE30\uBCF8: 30)`,
1288
- check: `${kleur8.bold("mimi-seed check")} \u2014 \uCD9C\uC2DC \uC804 Readiness \uC810\uAC80
1332
+ check: `${kleur9.bold("mimi-seed check")} \u2014 \uCD9C\uC2DC \uC804 Readiness \uC810\uAC80
1289
1333
 
1290
1334
  \uC635\uC158:
1291
1335
  --app <id> \uC571 ID \uC9C0\uC815
1292
1336
  --fail-on-blocker \uBE14\uB85C\uCEE4 \uC788\uC73C\uBA74 exit 1 (CI\uC6A9)`,
1293
- review: `${kleur8.bold("mimi-seed review")} \u2014 \uB9AC\uBDF0 \uB2F5\uBCC0 AI \uCD08\uC548 \uC0DD\uC131 \uBC0F Play Store \uAC8C\uC2DC
1337
+ review: `${kleur9.bold("mimi-seed review")} \u2014 \uB9AC\uBDF0 \uB2F5\uBCC0 AI \uCD08\uC548 \uC0DD\uC131 \uBC0F Play Store \uAC8C\uC2DC
1294
1338
 
1295
1339
  \uC635\uC158:
1296
1340
  --text <\uB0B4\uC6A9> \uB9AC\uBDF0 \uC6D0\uBB38 (\uBBF8\uC785\uB825 \uC2DC \uB300\uD654\uD615 \uD504\uB86C\uD504\uD2B8)
@@ -1302,7 +1346,7 @@ ${kleur8.dim("\uBE44TTY / CI \uD658\uACBD\uC5D0\uC11C\uB294 \uD504\uB86C\uD504\u
1302
1346
  --review-id <id> \uB9AC\uBDF0 ID (--apply \uC2DC \uD544\uC694)
1303
1347
  --package-name <p> \uD328\uD0A4\uC9C0\uBA85 (--apply \uC2DC \uD544\uC694)
1304
1348
  --no-interactive CI \uBAA8\uB4DC`,
1305
- deploy: `${kleur8.bold("mimi-seed deploy")} \u2014 \uC571 \uC790\uB3D9 \uBC30\uD3EC (CI \uBE4C\uB4DC \u2192 Play Store/App Store)
1349
+ deploy: `${kleur9.bold("mimi-seed deploy")} \u2014 \uC571 \uC790\uB3D9 \uBC30\uD3EC (CI \uBE4C\uB4DC \u2192 Play Store/App Store)
1306
1350
 
1307
1351
  \uC635\uC158:
1308
1352
  --platform android|ios \uBC30\uD3EC \uD50C\uB7AB\uD3FC (\uAE30\uBCF8: android)
@@ -1318,7 +1362,7 @@ ${kleur8.dim("\uBE44TTY / CI \uD658\uACBD\uC5D0\uC11C\uB294 \uD504\uB86C\uD504\u
1318
1362
  --workflow <file> GitHub workflow \uD30C\uC77C (\uC608: deploy.yml)
1319
1363
  --ref <branch|tag> GitHub/GitLab \uBE0C\uB79C\uCE58/\uD0DC\uADF8 (\uAE30\uBCF8: main)
1320
1364
  setup-jenkins / setup-github / setup-gitlab CI \uC124\uC815 \uB300\uD654\uD615 \uB4F1\uB85D`,
1321
- mcp: `${kleur8.bold("mimi-seed mcp")} \u2014 Claude/Codex MCP \uC5F0\uACB0
1365
+ mcp: `${kleur9.bold("mimi-seed mcp")} \u2014 Claude/Codex MCP \uC5F0\uACB0
1322
1366
 
1323
1367
  \uC11C\uBE0C\uBA85\uB839:
1324
1368
  mimi-seed mcp \uD604\uC7AC \uC124\uC815 + \uB4F1\uB85D \uC548\uB0B4
@@ -1329,35 +1373,37 @@ ${kleur8.dim("\uBE44TTY / CI \uD658\uACBD\uC5D0\uC11C\uB294 \uD504\uB86C\uD504\u
1329
1373
  function printCommandHelp(cmd) {
1330
1374
  const usage = CMD_USAGE[cmd];
1331
1375
  if (!usage) return false;
1332
- log3(usage);
1376
+ log4(usage);
1333
1377
  return true;
1334
1378
  }
1335
1379
  function printHelp() {
1336
- log3(`${kleur8.bold("mimi-seed")} \u2014 Claude Code/Codex\uC5D0\uC11C \uC571 \uCD9C\uC2DC \uC6B4\uC601
1380
+ log4(`${kleur9.bold("mimi-seed")} \u2014 Claude Code/Codex\uC5D0\uC11C \uC571 \uCD9C\uC2DC \uC6B4\uC601
1337
1381
 
1338
- ${kleur8.bold("\uBA85\uB839\uC5B4:")}
1339
- ${kleur8.cyan("mimi-seed init")} \uD604\uC7AC \uD504\uB85C\uC81D\uD2B8\uB97C Mimi Seed\uC5D0 \uC5F0\uACB0
1340
- ${kleur8.cyan("mimi-seed setup")} \uAC00\uC9C4 \uACC4\uC815\uC744 \uD55C \uBC88\uC5D0 \uC5F0\uACB0 (\uC548\uB0B4\uD615 \uB9C8\uBC95\uC0AC)
1341
- ${kleur8.cyan("mimi-seed status")} \uC5F0\uACB0 \uC0C1\uD0DC + \uB4F1\uB85D \uC571 \uBAA9\uB85D
1342
- ${kleur8.cyan("mimi-seed auth")} \uC790\uACA9\uC99D\uBA85 \uAC1C\uBCC4 \uC778\uC99D (Google / App Store / Play / Jenkins / CI \u2026)
1343
- ${kleur8.cyan("mimi-seed firebase")} Firebase \uC571 \uC0DD\uC131\xB7config \uB2E4\uC6B4\uB85C\uB4DC\xB7GA4 \uB9C1\uD06C
1344
- ${kleur8.cyan("mimi-seed admob")} AdMob \uACC4\uC815\xB7\uC571\xB7\uAD11\uACE0\uB2E8\uC704 \uC870\uD68C \uBC0F \uC0DD\uC131
1345
- ${kleur8.cyan("mimi-seed ga4")} GA4 property\xB7data stream \uC0DD\uC131\xB7\uC870\uD68C
1346
- ${kleur8.cyan("mimi-seed doctor")} \uD658\uACBD \uC9C4\uB2E8 (\uD1A0\uD070\xB7Git\xB7\uD504\uB85C\uC81D\uD2B8\xB7CI \uCCB4\uD06C)
1347
- ${kleur8.cyan("mimi-seed check")} \uCD9C\uC2DC \uC804 Readiness \uC810\uAC80
1348
- ${kleur8.cyan("mimi-seed notes")} \uB9B4\uB9AC\uC988 \uB178\uD2B8 \uC0DD\uC131 (git log \u2192 AI \u2192 \uB9C8\uCF13 \uC801\uC6A9)
1349
- ${kleur8.cyan("mimi-seed review")} \uB9AC\uBDF0 \uB2F5\uBCC0 AI \uCD08\uC548 \uC0DD\uC131 \uBC0F Play Store \uAC8C\uC2DC
1350
- ${kleur8.cyan("mimi-seed deploy")} \uC571 \uC790\uB3D9 \uBC30\uD3EC (CI \u2192 Play Store/App Store)
1351
- ${kleur8.cyan("mimi-seed mcp")} Claude/Codex MCP \uC5F0\uACB0 \uC548\uB0B4 \uBC0F Codex \uC124\uC815 \uC4F0\uAE30
1352
- ${kleur8.cyan("mimi-seed restart")} MCP \uC11C\uBC84 \uD504\uB85C\uC138\uC2A4 \uC7AC\uC2DC\uC791 (\uAE30\uBCF8: mimi-seed)
1353
- ${kleur8.cyan("mimi-seed logout")} \uB85C\uCEEC \uC124\uC815 \uC0AD\uC81C
1382
+ ${kleur9.bold("\uBA85\uB839\uC5B4:")}
1383
+ ${kleur9.cyan("mimi-seed init")} \uD604\uC7AC \uD504\uB85C\uC81D\uD2B8\uB97C Mimi Seed\uC5D0 \uC5F0\uACB0
1384
+ ${kleur9.cyan("mimi-seed setup")} \uAC00\uC9C4 \uACC4\uC815\uC744 \uD55C \uBC88\uC5D0 \uC5F0\uACB0 (\uC548\uB0B4\uD615 \uB9C8\uBC95\uC0AC)
1385
+ ${kleur9.cyan("mimi-seed lang")} \uCD9C\uB825 \uC5B8\uC5B4 (ko / en)
1386
+ ${kleur9.cyan("mimi-seed status")} \uC5F0\uACB0 \uC0C1\uD0DC + \uB4F1\uB85D \uC571 \uBAA9\uB85D
1387
+ ${kleur9.cyan("mimi-seed auth")} \uC790\uACA9\uC99D\uBA85 \uAC1C\uBCC4 \uC778\uC99D (Google / App Store / Play / Jenkins / CI \u2026)
1388
+ ${kleur9.cyan("mimi-seed firebase")} Firebase \uC571 \uC0DD\uC131\xB7config \uB2E4\uC6B4\uB85C\uB4DC\xB7GA4 \uB9C1\uD06C
1389
+ ${kleur9.cyan("mimi-seed admob")} AdMob \uACC4\uC815\xB7\uC571\xB7\uAD11\uACE0\uB2E8\uC704 \uC870\uD68C \uBC0F \uC0DD\uC131
1390
+ ${kleur9.cyan("mimi-seed ga4")} GA4 property\xB7data stream \uC0DD\uC131\xB7\uC870\uD68C
1391
+ ${kleur9.cyan("mimi-seed doctor")} \uD658\uACBD \uC9C4\uB2E8 (\uD1A0\uD070\xB7Git\xB7\uD504\uB85C\uC81D\uD2B8\xB7CI \uCCB4\uD06C)
1392
+ ${kleur9.cyan("mimi-seed check")} \uCD9C\uC2DC \uC804 Readiness \uC810\uAC80
1393
+ ${kleur9.cyan("mimi-seed notes")} \uB9B4\uB9AC\uC988 \uB178\uD2B8 \uC0DD\uC131 (git log \u2192 AI \u2192 \uB9C8\uCF13 \uC801\uC6A9)
1394
+ ${kleur9.cyan("mimi-seed review")} \uB9AC\uBDF0 \uB2F5\uBCC0 AI \uCD08\uC548 \uC0DD\uC131 \uBC0F Play Store \uAC8C\uC2DC
1395
+ ${kleur9.cyan("mimi-seed deploy")} \uC571 \uC790\uB3D9 \uBC30\uD3EC (CI \u2192 Play Store/App Store)
1396
+ ${kleur9.cyan("mimi-seed mcp")} Claude/Codex MCP \uC5F0\uACB0 \uC548\uB0B4 \uBC0F Codex \uC124\uC815 \uC4F0\uAE30
1397
+ ${kleur9.cyan("mimi-seed restart")} MCP \uC11C\uBC84 \uD504\uB85C\uC138\uC2A4 \uC7AC\uC2DC\uC791 (\uAE30\uBCF8: mimi-seed)
1398
+ ${kleur9.cyan("mimi-seed logout")} \uB85C\uCEEC \uC124\uC815 \uC0AD\uC81C
1354
1399
 
1355
- ${kleur8.dim("\uAC01 \uBA85\uB839 \uC0C1\uC138 \uC635\uC158:")} ${kleur8.cyan("mimi-seed <command> --help")}
1400
+ ${kleur9.dim("\uAC01 \uBA85\uB839 \uC0C1\uC138 \uC635\uC158:")} ${kleur9.cyan("mimi-seed <command> --help")}
1356
1401
 
1357
- ${kleur8.bold("\uD658\uACBD\uBCC0\uC218:")}
1402
+ ${kleur9.bold("\uD658\uACBD\uBCC0\uC218:")}
1358
1403
  MIMI_SEED_TOKEN PAT \uD1A0\uD070 (CI/CD \uBB34\uC778\uC99D \uBAA8\uB4DC)
1359
1404
  MIMI_SEED_WEB_BASE \uC11C\uBC84 \uC8FC\uC18C (\uAE30\uBCF8: https://mimi-seed.pryzm.gg)
1360
1405
  ANTHROPIC_API_KEY AI \uB178\uD2B8 \uC0DD\uC131 \uD65C\uC131\uD654 (\uC120\uD0DD)
1406
+ MIMI_SEED_LANG \uCD9C\uB825 \uC5B8\uC5B4 \uAC15\uC81C (ko / en) \u2014 settings.json \uBCF4\uB2E4 \uC6B0\uC120
1361
1407
  MIMI_SEED_GOOGLE_CLIENT_ID / _SECRET
1362
1408
  \uC9C1\uC811 \uB9CC\uB4E0 Google OAuth \uD074\uB77C\uC774\uC5B8\uD2B8 \uC0AC\uC6A9 (\uBBF8\uC9C0\uC815 \uC2DC \uB85C\uADF8\uC778 \uB54C \uC6F9 \uCF58\uC194\uC5D0\uC11C \uBC1B\uC544\uC634)
1363
1409
  `);
@@ -1376,6 +1422,9 @@ async function main() {
1376
1422
  case "setup":
1377
1423
  await cmdSetup(restArgs);
1378
1424
  break;
1425
+ case "lang":
1426
+ await cmdLang(restArgs);
1427
+ break;
1379
1428
  case "status":
1380
1429
  await cmdStatus();
1381
1430
  break;
@@ -1421,13 +1470,13 @@ async function main() {
1421
1470
  printHelp();
1422
1471
  break;
1423
1472
  default:
1424
- log3(kleur8.red(`\uC54C \uC218 \uC5C6\uB294 \uBA85\uB839: ${cmd}`));
1473
+ log4(kleur9.red(`\uC54C \uC218 \uC5C6\uB294 \uBA85\uB839: ${cmd}`));
1425
1474
  printHelp();
1426
1475
  process.exit(1);
1427
1476
  }
1428
1477
  } catch (e) {
1429
- log3(kleur8.red(`\uC624\uB958: ${e.message}`));
1430
- if (process.env.DEBUG) log3(e.stack ?? "");
1478
+ log4(kleur9.red(`\uC624\uB958: ${e.message}`));
1479
+ if (process.env.DEBUG) log4(e.stack ?? "");
1431
1480
  process.exit(1);
1432
1481
  }
1433
1482
  }