mimi-seed 0.19.9 → 0.19.11

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
@@ -11,7 +11,8 @@ npx mimi-seed check --local
11
11
  ```
12
12
 
13
13
  로그인 없이 현재 저장소의 앱 식별자, Android Target API, Google Play Billing 지원 상태를 먼저 검사합니다.
14
- 정책 결과에는 근거 파일과 공식 출처가 포함됩니다. 실제 스토어 상태까지 연결하려면 그다음 실행합니다.
14
+ 검사기는 CLI에 번들되어 전체 MCP 패키지를 추가 설치하지 않으며, 저장소 전용 모드에서는 네트워크도 호출하지
15
+ 않습니다. 정책 결과에는 근거 파일과 공식 출처가 포함됩니다. 실제 스토어 상태까지 연결하려면 그다음 실행합니다.
15
16
 
16
17
  ```bash
17
18
  npx mimi-seed init
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  catalog
4
- } from "./chunk-ZGMPOJRY.js";
4
+ } from "./chunk-TQHLWSFR.js";
5
5
 
6
6
  // src/mcp-client.ts
7
7
  var M = catalog(
@@ -118,6 +118,7 @@ var ko = {
118
118
  serverOk: "Mimi Seed \uC11C\uBC84 \uC5F0\uACB0\uB428",
119
119
  appCount: (n) => `\uC571 ${n}\uAC1C`,
120
120
  unknownService: (id) => `${id} (\uC54C \uC218 \uC5C6\uB294 \uC11C\uBE44\uC2A4)`,
121
+ credentialMismatch: (field, expected, actual) => `${field} \uBD88\uC77C\uCE58 \u2014 \uC694\uAD6C\uAC12 ${expected}, \uD604\uC7AC\uAC12 ${actual ?? "\uC5C6\uC74C"}`,
121
122
  credsHint: " \uC804\uBD80 \uC5F0\uACB0\uD558\uAE30: mimi-seed setup \xB7 OAuth \uC2E0\uC120\uB3C4: mimi-seed auth status\n",
122
123
  nodeTooOld: (v) => `${v} \u2014 v20 \uC774\uC0C1 \uD544\uC694 (.nvmrc \uCC38\uACE0)`,
123
124
  gitRepo: "Git \uC800\uC7A5\uC18C",
@@ -126,7 +127,7 @@ var ko = {
126
127
  noGit: "Git \uC800\uC7A5\uC18C \uC5C6\uC74C",
127
128
  noGitDetail: "mimi-seed notes \uC0AC\uC6A9 \uBD88\uAC00",
128
129
  noApp: "\uC571 \uAC10\uC9C0 \uC5C6\uC74C",
129
- noAppDetail: "app.json / build.gradle / Info.plist \uC5C6\uC74C",
130
+ noAppDetail: "Expo / Gradle / Xcode / Unity \uC571 \uC124\uC815 \uC5C6\uC74C",
130
131
  unnamed: "(\uC774\uB984 \uBBF8\uC0C1)",
131
132
  requirements: (proj) => `${proj} \uC694\uAD6C\uC0AC\uD56D (.mimi-seed.json)`,
132
133
  thisProject: "\uC774 \uD504\uB85C\uC81D\uD2B8"
@@ -220,6 +221,7 @@ MIMI_SEED_LANG takes precedence when set.`,
220
221
  serverOk: "Connected to Mimi Seed",
221
222
  appCount: (n) => `${n} app(s)`,
222
223
  unknownService: (id) => `${id} (unknown service)`,
224
+ credentialMismatch: (field, expected, actual) => `${field} mismatch \u2014 expected ${expected}, current ${actual ?? "missing"}`,
223
225
  credsHint: " Connect everything: mimi-seed setup \xB7 OAuth freshness: mimi-seed auth status\n",
224
226
  nodeTooOld: (v) => `${v} \u2014 v20+ required (see .nvmrc)`,
225
227
  gitRepo: "Git repository",
@@ -228,7 +230,7 @@ MIMI_SEED_LANG takes precedence when set.`,
228
230
  noGit: "Not a git repository",
229
231
  noGitDetail: "mimi-seed notes is unavailable",
230
232
  noApp: "No app detected",
231
- noAppDetail: "no app.json / build.gradle / Info.plist",
233
+ noAppDetail: "no Expo / Gradle / Xcode / Unity app configuration",
232
234
  unnamed: "(unnamed)",
233
235
  requirements: (proj) => `${proj} requirements (.mimi-seed.json)`,
234
236
  thisProject: "This project"
@@ -5,7 +5,7 @@ import {
5
5
  resolveLang,
6
6
  t,
7
7
  writeSettings
8
- } from "./chunk-ZGMPOJRY.js";
8
+ } from "./chunk-TQHLWSFR.js";
9
9
 
10
10
  // src/setup.ts
11
11
  import kleur2 from "kleur";
@@ -242,7 +242,14 @@ var CREDENTIALS = [
242
242
  docsAnchor: "app-store-connect",
243
243
  detect: (home) => {
244
244
  const cfg = readJson(home, "appstore.json");
245
- return cfg ? { present: true, detail: cfg.keyId ? `keyId ${cfg.keyId}` : void 0 } : { present: false };
245
+ return cfg ? {
246
+ present: true,
247
+ detail: cfg.keyId ? `keyId ${cfg.keyId}` : void 0,
248
+ identity: Object.fromEntries([
249
+ ["keyId", cfg.keyId],
250
+ ["issuerId", cfg.issuerId]
251
+ ].filter((entry) => typeof entry[1] === "string"))
252
+ } : { present: false };
246
253
  }
247
254
  },
248
255
  {
@@ -769,6 +776,37 @@ async function pathExists(p) {
769
776
  return false;
770
777
  }
771
778
  }
779
+ async function importedJsonObjects(configPath, text, root) {
780
+ const result = /* @__PURE__ */ new Map();
781
+ const imports = [
782
+ ...text.matchAll(/\bimport\s+([A-Za-z_$][\w$]*)\s+from\s+["']([^"']+\.json)["']/g),
783
+ ...text.matchAll(/\bconst\s+([A-Za-z_$][\w$]*)\s*=\s*require\(\s*["']([^"']+\.json)["']\s*\)/g)
784
+ ];
785
+ for (const match of imports) {
786
+ if (!match[2].startsWith(".")) continue;
787
+ const candidate = path5.resolve(path5.dirname(configPath), match[2]);
788
+ const relative = path5.relative(root, candidate);
789
+ if (relative.startsWith(`..${path5.sep}`) || relative === ".." || path5.isAbsolute(relative)) continue;
790
+ const jsonText = await readIfExists(candidate);
791
+ if (!jsonText) continue;
792
+ try {
793
+ const json = JSON.parse(jsonText);
794
+ if (json && typeof json === "object" && !Array.isArray(json)) {
795
+ result.set(match[1], json);
796
+ }
797
+ } catch {
798
+ }
799
+ }
800
+ return result;
801
+ }
802
+ function importedMember(text, block, field, imports) {
803
+ const match = new RegExp(
804
+ `\\b${block}\\s*:\\s*\\{[\\s\\S]{0,5000}?\\b${field}\\s*:\\s*([A-Za-z_$][\\w$]*)\\.([A-Za-z_$][\\w$]*)`
805
+ ).exec(text);
806
+ if (!match) return void 0;
807
+ const value = imports.get(match[1])?.[match[2]];
808
+ return typeof value === "string" ? value : void 0;
809
+ }
772
810
  async function walk(root, match, maxDepth = 5) {
773
811
  const found = [];
774
812
  const skipDirs = /* @__PURE__ */ new Set([
@@ -823,6 +861,17 @@ async function detectHints(cwd) {
823
861
  } catch {
824
862
  }
825
863
  }
864
+ for (const fname of ["app.config.js", "app.config.cjs", "app.config.mjs", "app.config.ts"]) {
865
+ const configPath = path5.join(cwd, fname);
866
+ const txt = await readIfExists(configPath);
867
+ if (!txt) continue;
868
+ const imports = await importedJsonObjects(configPath, txt, cwd);
869
+ const pkg = txt.match(/\bandroid\s*:\s*\{[\s\S]{0,5000}?\bpackage\s*:\s*["']([^"']+)["']/)?.[1] ?? importedMember(txt, "android", "package", imports);
870
+ const bid = txt.match(/\bios\s*:\s*\{[\s\S]{0,5000}?\bbundleIdentifier\s*:\s*["']([^"']+)["']/)?.[1] ?? importedMember(txt, "ios", "bundleIdentifier", imports);
871
+ if (pkg || bid) {
872
+ hints.push({ packageName: pkg, bundleId: bid, source: [fname] });
873
+ }
874
+ }
826
875
  const gradleFiles = await walk(
827
876
  cwd,
828
877
  (n) => n === "build.gradle" || n === "build.gradle.kts",
@@ -867,6 +916,34 @@ async function detectHints(cwd) {
867
916
  }
868
917
  }
869
918
  }
919
+ const unitySettings = path5.join(cwd, "ProjectSettings", "ProjectSettings.asset");
920
+ const unityText = await readIfExists(unitySettings);
921
+ if (unityText) {
922
+ const lines = unityText.split(/\r?\n/);
923
+ const identifierStart = lines.findIndex((line) => /^\s*applicationIdentifier:\s*$/.test(line));
924
+ const baseIndent = identifierStart >= 0 ? lines[identifierStart].match(/^\s*/)?.[0].length ?? 0 : 0;
925
+ let packageName;
926
+ let bundleId;
927
+ if (identifierStart >= 0) {
928
+ for (const line of lines.slice(identifierStart + 1)) {
929
+ if (!line.trim()) continue;
930
+ const indent = line.match(/^\s*/)?.[0].length ?? 0;
931
+ if (indent <= baseIndent) break;
932
+ const entry = line.match(/^\s+(Android|iPhone|iOS):\s*([^\s#]+)\s*$/);
933
+ if (entry?.[1] === "Android") packageName = entry[2];
934
+ if (entry && entry[1] !== "Android") bundleId = entry[2];
935
+ }
936
+ }
937
+ const name = unityText.match(/^\s*productName:\s*(.+?)\s*$/m)?.[1];
938
+ if (packageName || bundleId) {
939
+ hints.push({
940
+ name,
941
+ packageName,
942
+ bundleId,
943
+ source: [path5.relative(cwd, unitySettings)]
944
+ });
945
+ }
946
+ }
870
947
  const pkgJson = await readIfExists(path5.join(cwd, "package.json"));
871
948
  if (pkgJson) {
872
949
  try {
@@ -903,7 +980,7 @@ async function detectHints(cwd) {
903
980
  return merged.filter((h) => h.packageName || h.bundleId);
904
981
  }
905
982
  async function hasAnyProjectSignal(cwd) {
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"));
983
+ 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")) || await pathExists(path5.join(cwd, "ProjectSettings", "ProjectSettings.asset"));
907
984
  }
908
985
 
909
986
  // src/deploy.ts
@@ -1595,7 +1672,7 @@ async function cmdDeploy(argv) {
1595
1672
  }
1596
1673
  let appId = args.appId;
1597
1674
  if (!appId) {
1598
- const { mcpCall } = await import("./mcp-client-DZNDKAGQ.js");
1675
+ const { mcpCall } = await import("./mcp-client-L5BQ5VG4.js");
1599
1676
  const r = await mcpCall(cfg.endpoint, cfg.token, "list_apps", {});
1600
1677
  if (!r.isError) {
1601
1678
  try {