mimi-seed 0.19.7 → 0.19.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -6,6 +6,13 @@ git log에서 릴리즈 노트를 생성하고, 출시 전 위험 요소를 자
6
6
 
7
7
  ## 빠른 시작
8
8
 
9
+ ```bash
10
+ npx mimi-seed check --local
11
+ ```
12
+
13
+ 로그인 없이 현재 저장소의 앱 식별자, Android Target API, Google Play Billing 지원 상태를 먼저 검사합니다.
14
+ 정책 결과에는 근거 파일과 공식 출처가 포함됩니다. 실제 스토어 상태까지 연결하려면 그다음 실행합니다.
15
+
9
16
  ```bash
10
17
  npx mimi-seed init
11
18
  ```
@@ -21,7 +28,7 @@ npx mimi-seed init
21
28
  | `mimi-seed status` | 연결 상태 + 등록 앱 목록 |
22
29
  | `mimi-seed auth` | 자격증명 개별 인증 — `login` / `appstore` / `playstore` / `bigquery` / `jenkins` / `ci` / `googleads` / `facebook` / `instagram` / `threads` |
23
30
  | `mimi-seed doctor` | 환경 진단 (토큰·Git·앱·CI 한 번에 체크) |
24
- | `mimi-seed check` | 출시 Readiness 점검 (점수 + 블로커) |
31
+ | `mimi-seed check` | 계정이 없으면 로컬 Release Doctor, 연결 후에는 원격 Readiness 점검 |
25
32
  | `mimi-seed notes` | AI 릴리즈 노트 생성 (git log → 3 톤 → 다국어 → 적용) |
26
33
  | `mimi-seed review` | AI 리뷰 답변 초안 생성 및 Play Store 게시 |
27
34
  | `mimi-seed deploy` | 앱 자동 배포 파이프라인 (CI 빌드 → 릴리즈 노트 → 스토어 적용) |
@@ -76,13 +83,23 @@ mimi-seed notes --locale ko,en-US,ja
76
83
 
77
84
  ## mimi-seed check
78
85
 
79
- 출시 Readiness 점수와 블로커를 확인합니다.
86
+ 계정 연결 전에는 현재 저장소를 읽기 전용으로 검사하고, 연결 후에는 원격 Readiness 점수와 블로커를
87
+ 확인합니다. `--local`은 연결 상태와 관계없이 로컬 검사만 실행합니다.
80
88
 
81
89
  ```bash
82
90
  mimi-seed check
83
91
 
92
+ # 로그인 없이 저장소만 검사
93
+ mimi-seed check --local
94
+
95
+ # 모노레포의 특정 앱 검사
96
+ mimi-seed check --local --path apps/mobile
97
+
84
98
  # CI에서 블로커 있으면 exit 1
85
- mimi-seed check --fail-on-blocker
99
+ mimi-seed check --local --fail-on-blocker
100
+
101
+ # JSON 보고서
102
+ mimi-seed check --local --json
86
103
  ```
87
104
 
88
105
  ### 옵션
@@ -90,6 +107,9 @@ mimi-seed check --fail-on-blocker
90
107
  | 옵션 | 설명 |
91
108
  |------|------|
92
109
  | `--app <id>` | 앱 ID 지정 (기본: 첫 번째 등록 앱) |
110
+ | `--local` | 로그인 없이 현재 저장소만 검사 |
111
+ | `--path <dir>` | 로컬 검사 대상 경로 (기본: 현재 폴더) |
112
+ | `--json` | 로컬 검사 결과를 JSON으로 출력 |
93
113
  | `--fail-on-blocker` | 블로커 존재 시 exit 1 (CI/CD용) |
94
114
 
95
115
  ---
@@ -631,22 +631,71 @@ function planSetup(detected, opts = {}) {
631
631
 
632
632
  // src/mcp-bin.ts
633
633
  import { spawn, spawnSync } from "child_process";
634
+ import { existsSync, readFileSync } from "fs";
635
+ import path3 from "path";
634
636
  var MCP_PKG = "@yoonion/mimi-seed-mcp";
635
- function resolveOnPath(bin) {
636
- if (process.env.MIMI_SEED_FORCE_NPX) return false;
637
- const probe = process.platform === "win32" ? "where" : "which";
638
- const r = spawnSync(probe, [bin], { stdio: "ignore", shell: true });
639
- return r.status === 0;
637
+ function resolveOnPath(bin, honorForceNpx = true) {
638
+ if (honorForceNpx && process.env.MIMI_SEED_FORCE_NPX) return null;
639
+ if (process.platform === "win32") {
640
+ const pathKey = Object.keys(process.env).find((key) => key.toLowerCase() === "path");
641
+ const directories = (pathKey ? process.env[pathKey] ?? "" : "").split(path3.delimiter).filter(Boolean);
642
+ const names = bin.toLowerCase().endsWith(".cmd") ? [bin] : [`${bin}.cmd`, bin];
643
+ for (const directory of directories) {
644
+ for (const name of names) {
645
+ const candidate = path3.join(directory.replace(/^"|"$/g, ""), name);
646
+ if (existsSync(candidate)) return candidate;
647
+ }
648
+ }
649
+ return null;
650
+ }
651
+ const probe = "which";
652
+ const result = spawnSync(probe, [bin], { encoding: "utf8", shell: false });
653
+ if (result.status !== 0) return null;
654
+ const candidates = result.stdout.split(/\r?\n/).map((line) => line.trim()).filter(Boolean);
655
+ return candidates[0] ?? null;
656
+ }
657
+ function resolveWindowsShimTarget(shimPath, source) {
658
+ const matches = [...source.matchAll(/["']([^"']+\.js)["']\s+%\*/gi)];
659
+ const raw = matches.at(-1)?.[1];
660
+ if (!raw) return null;
661
+ return path3.win32.normalize(raw.replace(/%~?dp0%?/gi, `${path3.win32.dirname(shimPath)}${path3.win32.sep}`));
662
+ }
663
+ function npxCliPath(shimPath) {
664
+ const candidates = [
665
+ shimPath ? path3.join(path3.dirname(shimPath), "node_modules", "npm", "bin", "npx-cli.js") : "",
666
+ path3.join(path3.dirname(process.execPath), "node_modules", "npm", "bin", "npx-cli.js"),
667
+ process.env.npm_execpath ? path3.join(path3.dirname(process.env.npm_execpath), "npx-cli.js") : ""
668
+ ];
669
+ return candidates.find((candidate) => candidate && existsSync(candidate)) ?? null;
670
+ }
671
+ function windowsNodeTarget(command, shimPath) {
672
+ if (command === "npx") return npxCliPath(shimPath);
673
+ if (!shimPath) return null;
674
+ try {
675
+ const target = resolveWindowsShimTarget(shimPath, readFileSync(shimPath, "utf8"));
676
+ return target && existsSync(target) ? target : null;
677
+ } catch {
678
+ return null;
679
+ }
640
680
  }
641
681
  async function runMcpBin(bin, extraArgs = []) {
642
- const local = resolveOnPath(bin);
643
- const cmd = local ? bin : "npx";
682
+ const localPath = resolveOnPath(bin);
683
+ const cmd = localPath ? bin : "npx";
644
684
  const pkg = process.env.MIMI_SEED_FORCE_NPX ? `${MCP_PKG}@latest` : MCP_PKG;
645
- const args = local ? extraArgs : ["-y", pkg, bin, ...extraArgs];
685
+ const args = localPath ? extraArgs : ["-y", pkg, bin, ...extraArgs];
646
686
  return new Promise((resolve) => {
647
- const child = spawn(cmd, args, {
687
+ const shimPath = process.platform === "win32" ? localPath ?? resolveOnPath(cmd, false) : null;
688
+ const nodeTarget = process.platform === "win32" ? windowsNodeTarget(cmd, shimPath) : null;
689
+ if (process.platform === "win32" && !nodeTarget) {
690
+ process.stderr.write(t().auth.npxFailed(cmd, `could not resolve the JavaScript entrypoint for ${shimPath ?? cmd}`));
691
+ resolve(1);
692
+ return;
693
+ }
694
+ const executable = process.platform === "win32" ? process.execPath : localPath ?? cmd;
695
+ const childArgs = nodeTarget ? [nodeTarget, ...args] : args;
696
+ const child = spawn(executable, childArgs, {
648
697
  stdio: "inherit",
649
- shell: true,
698
+ shell: false,
650
699
  env: { ...process.env, MIMI_SEED_LANG: resolveLang() }
651
700
  });
652
701
  child.on("error", (e) => {
@@ -660,22 +709,22 @@ async function runMcpBin(bin, extraArgs = []) {
660
709
  // src/jenkins-config.ts
661
710
  import fs3 from "fs";
662
711
  import os2 from "os";
663
- import path3 from "path";
664
- var CONFIG_DIR = path3.join(os2.homedir(), ".mimi-seed");
665
- var JENKINS_PATH = path3.join(CONFIG_DIR, "jenkins.json");
666
- var LEGACY_PATH = path3.join(CONFIG_DIR, "config.json");
712
+ import path4 from "path";
713
+ var CONFIG_DIR = path4.join(os2.homedir(), ".mimi-seed");
714
+ var JENKINS_PATH = path4.join(CONFIG_DIR, "jenkins.json");
715
+ var LEGACY_PATH = path4.join(CONFIG_DIR, "config.json");
667
716
  function loadJenkinsConfig(home = os2.homedir()) {
668
717
  try {
669
- const p = path3.join(home, ".mimi-seed", "jenkins.json");
718
+ const p = path4.join(home, ".mimi-seed", "jenkins.json");
670
719
  return JSON.parse(fs3.readFileSync(p, "utf-8"));
671
720
  } catch {
672
721
  return null;
673
722
  }
674
723
  }
675
724
  function migrateLegacyJenkins(home = os2.homedir()) {
676
- const dir = path3.join(home, ".mimi-seed");
677
- const jenkinsPath = path3.join(dir, "jenkins.json");
678
- const legacyPath = path3.join(dir, "config.json");
725
+ const dir = path4.join(home, ".mimi-seed");
726
+ const jenkinsPath = path4.join(dir, "jenkins.json");
727
+ const legacyPath = path4.join(dir, "config.json");
679
728
  if (fs3.existsSync(jenkinsPath)) return false;
680
729
  let legacy;
681
730
  try {
@@ -704,7 +753,7 @@ function migrateLegacyJenkins(home = os2.homedir()) {
704
753
 
705
754
  // src/detect.ts
706
755
  import fs4 from "fs/promises";
707
- import path4 from "path";
756
+ import path5 from "path";
708
757
  async function readIfExists(p) {
709
758
  try {
710
759
  return await fs4.readFile(p, "utf8");
@@ -743,9 +792,9 @@ async function walk(root, match, maxDepth = 5) {
743
792
  for (const e of entries) {
744
793
  if (e.isDirectory()) {
745
794
  if (skipDirs.has(e.name)) continue;
746
- await visit(path4.join(dir, e.name), depth + 1);
795
+ await visit(path5.join(dir, e.name), depth + 1);
747
796
  } else if (e.isFile() && match(e.name)) {
748
- found.push(path4.join(dir, e.name));
797
+ found.push(path5.join(dir, e.name));
749
798
  }
750
799
  }
751
800
  }
@@ -755,7 +804,7 @@ async function walk(root, match, maxDepth = 5) {
755
804
  async function detectHints(cwd) {
756
805
  const hints = [];
757
806
  for (const fname of ["app.json", "app.config.json"]) {
758
- const txt = await readIfExists(path4.join(cwd, fname));
807
+ const txt = await readIfExists(path5.join(cwd, fname));
759
808
  if (!txt) continue;
760
809
  try {
761
810
  const json = JSON.parse(txt);
@@ -786,7 +835,7 @@ async function detectHints(cwd) {
786
835
  if (m?.[1]) {
787
836
  const pkg = m[1];
788
837
  if (!hints.some((h) => h.packageName === pkg)) {
789
- hints.push({ packageName: pkg, source: [path4.relative(cwd, f)] });
838
+ hints.push({ packageName: pkg, source: [path5.relative(cwd, f)] });
790
839
  }
791
840
  }
792
841
  }
@@ -801,7 +850,7 @@ async function detectHints(cwd) {
801
850
  const bid = m[1];
802
851
  if (bid.includes("$(PRODUCT_BUNDLE_IDENTIFIER)")) continue;
803
852
  if (!hints.some((h) => h.bundleId === bid)) {
804
- hints.push({ bundleId: bid, source: [path4.relative(cwd, f)] });
853
+ hints.push({ bundleId: bid, source: [path5.relative(cwd, f)] });
805
854
  }
806
855
  }
807
856
  }
@@ -814,11 +863,11 @@ async function detectHints(cwd) {
814
863
  const bid = m[1].trim().replace(/^["']|["']$/g, "");
815
864
  if (!bid || bid.includes("$")) continue;
816
865
  if (!hints.some((h) => h.bundleId === bid)) {
817
- hints.push({ bundleId: bid, source: [path4.relative(cwd, f)] });
866
+ hints.push({ bundleId: bid, source: [path5.relative(cwd, f)] });
818
867
  }
819
868
  }
820
869
  }
821
- const pkgJson = await readIfExists(path4.join(cwd, "package.json"));
870
+ const pkgJson = await readIfExists(path5.join(cwd, "package.json"));
822
871
  if (pkgJson) {
823
872
  try {
824
873
  const json = JSON.parse(pkgJson);
@@ -854,7 +903,7 @@ async function detectHints(cwd) {
854
903
  return merged.filter((h) => h.packageName || h.bundleId);
855
904
  }
856
905
  async function hasAnyProjectSignal(cwd) {
857
- return await pathExists(path4.join(cwd, "package.json")) || await pathExists(path4.join(cwd, "app.json")) || await pathExists(path4.join(cwd, "android")) || await pathExists(path4.join(cwd, "ios"));
906
+ return await pathExists(path5.join(cwd, "package.json")) || await pathExists(path5.join(cwd, "app.json")) || await pathExists(path5.join(cwd, "android")) || await pathExists(path5.join(cwd, "ios"));
858
907
  }
859
908
 
860
909
  // src/deploy.ts
@@ -863,10 +912,10 @@ import * as readline from "readline";
863
912
 
864
913
  // src/config.ts
865
914
  import fs5 from "fs/promises";
866
- import path5 from "path";
915
+ import path6 from "path";
867
916
  import os3 from "os";
868
- var CONFIG_DIR2 = path5.join(os3.homedir(), ".mimi-seed");
869
- var CONFIG_PATH = path5.join(CONFIG_DIR2, "config.json");
917
+ var CONFIG_DIR2 = path6.join(os3.homedir(), ".mimi-seed");
918
+ var CONFIG_PATH = path6.join(CONFIG_DIR2, "config.json");
870
919
  async function readConfig() {
871
920
  try {
872
921
  const txt = await fs5.readFile(CONFIG_PATH, "utf8");
@@ -903,9 +952,9 @@ async function getEffectiveConfig() {
903
952
 
904
953
  // src/ci-providers.ts
905
954
  import fs6 from "fs";
906
- import path6 from "path";
955
+ import path7 from "path";
907
956
  import os4 from "os";
908
- var CI_CONFIG_PATH = path6.join(os4.homedir(), ".mimi-seed", "ci.json");
957
+ var CI_CONFIG_PATH = path7.join(os4.homedir(), ".mimi-seed", "ci.json");
909
958
  var M = catalog(
910
959
  {
911
960
  badToken: (provider, status) => `${provider} ${status} \u2014 \uD1A0\uD070\uC774 \uC720\uD6A8\uD558\uC9C0 \uC54A\uC544`,
@@ -937,7 +986,7 @@ function normalizeHost(host) {
937
986
  return withScheme.replace(/\/+$/, "");
938
987
  }
939
988
  function saveCiProviderConfig(cfg) {
940
- const dir = path6.dirname(CI_CONFIG_PATH);
989
+ const dir = path7.dirname(CI_CONFIG_PATH);
941
990
  if (!fs6.existsSync(dir)) {
942
991
  fs6.mkdirSync(dir, { recursive: true, mode: 448 });
943
992
  }
package/dist/index.js CHANGED
@@ -22,7 +22,7 @@ import {
22
22
  runMcpBin,
23
23
  tryCredById,
24
24
  writeConfig
25
- } from "./chunk-OXYELVMI.js";
25
+ } from "./chunk-KY6LI3CK.js";
26
26
  import {
27
27
  catalog,
28
28
  isLang,
@@ -263,6 +263,11 @@ import kleur2 from "kleur";
263
263
  var M2 = catalog(
264
264
  {
265
265
  noAccount: "\uC5F0\uACB0\uB41C \uACC4\uC815 \uC5C6\uC74C. `mimi-seed init` \uC2E4\uD589.\n",
266
+ missingOptionValue: (option) => `${option} \uB4A4\uC5D0 \uAC12\uC744 \uC785\uB825\uD558\uC138\uC694.`,
267
+ unknownOption: (option) => `\uC54C \uC218 \uC5C6\uB294 check \uC635\uC158: ${option}`,
268
+ unexpectedArgument: (value) => `\uC608\uC0C1\uD558\uC9C0 \uC54A\uC740 check \uC778\uC790: ${value}`,
269
+ localAppConflict: "--app\uC740 \uC6D0\uACA9 \uAC80\uC0AC \uC804\uC6A9\uC774\uBBC0\uB85C --local, --path, --json\uACFC \uD568\uAED8 \uC0AC\uC6A9\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.\n",
270
+ localStarting: "Release Doctor \uC2E4\uD589 \uC911\u2026 \uCCAB \uC2E4\uD589\uC740 \uAC80\uC0AC\uAE30 \uB2E4\uC6B4\uB85C\uB4DC\uB85C \uC2DC\uAC04\uC774 \uAC78\uB9B4 \uC218 \uC788\uC2B5\uB2C8\uB2E4.\n",
266
271
  title: "mimi-seed check \u2014 \uCD9C\uC2DC \uC804 \uC810\uAC80\n\n",
267
272
  appsFailed: (msg) => `\uC571 \uBAA9\uB85D \uC870\uD68C \uC2E4\uD328: ${msg}
268
273
  `,
@@ -294,6 +299,11 @@ var M2 = catalog(
294
299
  },
295
300
  {
296
301
  noAccount: "No account connected. Run `mimi-seed init`.\n",
302
+ missingOptionValue: (option) => `Provide a value after ${option}.`,
303
+ unknownOption: (option) => `Unknown check option: ${option}`,
304
+ unexpectedArgument: (value) => `Unexpected check argument: ${value}`,
305
+ localAppConflict: "--app is remote-only and cannot be combined with --local, --path, or --json.\n",
306
+ localStarting: "Running Release Doctor\u2026 the first run may take longer while the checker downloads.\n",
297
307
  title: "mimi-seed check \u2014 pre-launch check\n\n",
298
308
  appsFailed: (msg) => `Failed to list apps: ${msg}
299
309
  `,
@@ -324,11 +334,30 @@ Score: ${bar}
324
334
  `
325
335
  }
326
336
  );
327
- function parseArgs(argv) {
328
- const args = { failOnBlocker: false };
337
+ function parseCheckArgs(argv) {
338
+ const args = {
339
+ projectPath: process.cwd(),
340
+ projectPathExplicit: false,
341
+ failOnBlocker: false,
342
+ local: false,
343
+ json: false
344
+ };
345
+ const takeValue = (option, index) => {
346
+ const value = argv[index + 1];
347
+ if (!value || value.startsWith("--")) throw new Error(M2().missingOptionValue(option));
348
+ return value;
349
+ };
329
350
  for (let i = 0; i < argv.length; i++) {
330
- if (argv[i] === "--app" && argv[i + 1]) args.appId = argv[++i];
331
- if (argv[i] === "--fail-on-blocker") args.failOnBlocker = true;
351
+ const token = argv[i];
352
+ if (token === "--app") args.appId = takeValue(token, i++);
353
+ else if (token === "--path") {
354
+ args.projectPath = takeValue(token, i++);
355
+ args.projectPathExplicit = true;
356
+ } else if (token === "--fail-on-blocker") args.failOnBlocker = true;
357
+ else if (token === "--local") args.local = true;
358
+ else if (token === "--json") args.json = true;
359
+ else if (token.startsWith("-")) throw new Error(M2().unknownOption(token));
360
+ else throw new Error(M2().unexpectedArgument(token));
332
361
  }
333
362
  return args;
334
363
  }
@@ -345,11 +374,35 @@ var MODULE_LABELS = {
345
374
  checklist: "Checklist"
346
375
  };
347
376
  async function cmdCheck(argv) {
348
- const args = parseArgs(argv);
377
+ let args;
378
+ try {
379
+ args = parseCheckArgs(argv);
380
+ } catch (error) {
381
+ process.stderr.write(kleur2.red(`${error instanceof Error ? error.message : String(error)}
382
+ `));
383
+ process.exitCode = 2;
384
+ return;
385
+ }
349
386
  const cfg = await getEffectiveConfig();
350
- if (!cfg) {
351
- process.stdout.write(kleur2.red(M2().noAccount));
352
- process.exit(1);
387
+ const localRequested = args.local || args.json || args.projectPathExplicit;
388
+ if (args.appId && localRequested) {
389
+ process.stderr.write(kleur2.red(M2().localAppConflict));
390
+ process.exitCode = 2;
391
+ return;
392
+ }
393
+ if (args.appId && !cfg) {
394
+ process.stderr.write(kleur2.red(M2().noAccount));
395
+ process.exitCode = 1;
396
+ return;
397
+ }
398
+ if (localRequested || !cfg) {
399
+ const doctorArgs = [args.projectPath];
400
+ if (args.json) doctorArgs.push("--json");
401
+ if (args.failOnBlocker) doctorArgs.push("--fail-on-blocker");
402
+ if (!args.json) process.stderr.write(kleur2.dim(M2().localStarting));
403
+ const exitCode = await runMcpBin("mimi-seed-release-doctor", doctorArgs);
404
+ if (exitCode !== 0) process.exit(exitCode);
405
+ return;
353
406
  }
354
407
  process.stdout.write(kleur2.bold(M2().title));
355
408
  const appsResult = await mcpCall(cfg.endpoint, cfg.token, "list_apps", {});
@@ -554,7 +607,7 @@ Update now.`,
554
607
  `
555
608
  }
556
609
  );
557
- function parseArgs2(argv) {
610
+ function parseArgs(argv) {
558
611
  const args = { to: "HEAD", locales: ["ko", "en-US"], apply: false, noInteractive: false, limit: 30 };
559
612
  for (let i = 0; i < argv.length; i++) {
560
613
  if (argv[i] === "--from" && argv[i + 1]) args.from = argv[++i];
@@ -611,7 +664,7 @@ function parseFirstApp(text) {
611
664
  return null;
612
665
  }
613
666
  async function cmdNotes(argv) {
614
- const args = parseArgs2(argv);
667
+ const args = parseArgs(argv);
615
668
  const cwd = process.cwd();
616
669
  process.stdout.write(kleur3.bold(M3().title));
617
670
  if (!isGitRepo(cwd)) {
@@ -820,7 +873,7 @@ Respond with JSON only: { "reply": "the reply text" }`,
820
873
  posted: "\u2713 Reply posted\n"
821
874
  }
822
875
  );
823
- function parseArgs3(argv) {
876
+ function parseArgs2(argv) {
824
877
  const args = { tone: "friendly", language: "ko", apply: false, noInteractive: false };
825
878
  for (let i = 0; i < argv.length; i++) {
826
879
  if (argv[i] === "--text" && argv[i + 1]) args.text = argv[++i];
@@ -877,7 +930,7 @@ async function generateReply(opts) {
877
930
  return parsed.reply;
878
931
  }
879
932
  async function cmdReview(argv) {
880
- const args = parseArgs3(argv);
933
+ const args = parseArgs2(argv);
881
934
  process.stdout.write(kleur4.bold(M4().title));
882
935
  if (!process.env.ANTHROPIC_API_KEY) {
883
936
  process.stdout.write(kleur4.red(M4().noApiKey));
@@ -1068,7 +1121,7 @@ async function cmdAuth(args) {
1068
1121
  if (sub === "threads") return void exitWith(await runMcpBin("mimi-seed-social-auth", ["threads", ...rest]));
1069
1122
  if (sub === "tiktok") return void exitWith(await runMcpBin("mimi-seed-tiktok-business-auth", rest));
1070
1123
  if (sub === "ci") {
1071
- const { cmdSetup: cmdSetup2 } = await import("./setup-PEHGP5MD.js");
1124
+ const { cmdSetup: cmdSetup2 } = await import("./setup-RI2NDOZR.js");
1072
1125
  await cmdSetup2(["--only", "github,gitlab", "--reconnect", "github,gitlab"]);
1073
1126
  return;
1074
1127
  }
@@ -1613,6 +1666,9 @@ ${kleur9.dim("setup \uB9C8\uBC95\uC0AC\uAC00 \uCCAB \uC2E4\uD589 \uB54C \uBB3C\u
1613
1666
 
1614
1667
  \uC635\uC158:
1615
1668
  --app <id> \uC571 ID \uC9C0\uC815
1669
+ --local \uB85C\uADF8\uC778 \uC5C6\uC774 \uD604\uC7AC \uC800\uC7A5\uC18C\uB9CC \uAC80\uC0AC
1670
+ --path <dir> \uB85C\uCEEC \uAC80\uC0AC \uB300\uC0C1 \uACBD\uB85C (\uAE30\uBCF8: \uD604\uC7AC \uD3F4\uB354)
1671
+ --json \uB85C\uCEEC \uAC80\uC0AC \uACB0\uACFC\uB97C JSON\uC73C\uB85C \uCD9C\uB825
1616
1672
  --fail-on-blocker \uBE14\uB85C\uCEE4 \uC788\uC73C\uBA74 exit 1 (CI\uC6A9)`,
1617
1673
  review: `${kleur9.bold("mimi-seed review")} \u2014 \uB9AC\uBDF0 \uB2F5\uBCC0 AI \uCD08\uC548 \uC0DD\uC131 \uBC0F Play Store \uAC8C\uC2DC
1618
1674
 
@@ -1779,6 +1835,9 @@ Options:
1779
1835
 
1780
1836
  Options:
1781
1837
  --app <id> app ID
1838
+ --local inspect the current repository without signing in
1839
+ --path <dir> local project path (default: current directory)
1840
+ --json print the local report as JSON
1782
1841
  --fail-on-blocker exit 1 if a blocker is found (for CI)`,
1783
1842
  review: `${kleur9.bold("mimi-seed review")} \u2014 draft a review reply with AI and post it to the Play Store
1784
1843
 
@@ -3,7 +3,7 @@ import {
3
3
  cmdSetup,
4
4
  parseSetupArgs,
5
5
  resolveMode
6
- } from "./chunk-OXYELVMI.js";
6
+ } from "./chunk-KY6LI3CK.js";
7
7
  import "./chunk-ZGMPOJRY.js";
8
8
  export {
9
9
  cmdSetup,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mimi-seed",
3
- "version": "0.19.7",
3
+ "version": "0.19.9",
4
4
  "description": "Mimi Seed CLI \u2014 Claude Code\uc640 Codex\uc5d0\uc11c \uc571 \ucd9c\uc2dc \uc6b4\uc601\uc744 \uad00\ub9ac\ud569\ub2c8\ub2e4.",
5
5
  "bin": {
6
6
  "mimi-seed": "dist/index.js"