mimi-seed 0.21.2 → 0.21.3

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.
@@ -466,7 +466,10 @@ var CREDENTIALS = [
466
466
  docsAnchor: "google-ads",
467
467
  detect: (home) => {
468
468
  const cfg = readJson(home, "google-ads.json");
469
- return cfg?.customerId ? { present: true, detail: cfg.customerId } : { present: false };
469
+ const isId = (v) => typeof v === "string" && v.trim() !== "" || typeof v === "number" && Number.isSafeInteger(v) && v > 0;
470
+ const login = cfg?.loginCustomerId;
471
+ const loginOk = login === void 0 || login === null || login === "" || isId(login);
472
+ return typeof cfg?.developerToken === "string" && cfg.developerToken && isId(cfg.customerId) && loginOk ? { present: true, detail: String(cfg.customerId) } : { present: false };
470
473
  }
471
474
  },
472
475
  {
@@ -668,7 +671,7 @@ function planSetup(detected, opts = {}) {
668
671
  // src/mcp-bin.ts
669
672
  import { spawn, spawnSync } from "child_process";
670
673
  import { existsSync, readFileSync } from "fs";
671
- import path4 from "path";
674
+ import path5 from "path";
672
675
  import { fileURLToPath } from "url";
673
676
 
674
677
  // src/i18n.ts
@@ -893,19 +896,42 @@ function t() {
893
896
  }
894
897
 
895
898
  // package.json
896
- var version = "0.21.2";
899
+ var version = "0.21.3";
900
+
901
+ // src/lib/windows-path.ts
902
+ import path4 from "path";
903
+ function absoluteWindowsPathDirs(env = process.env) {
904
+ const key = Object.keys(env).find((k) => k.toLowerCase() === "path");
905
+ const value = key ? env[key] ?? "" : "";
906
+ const dirs = [];
907
+ const flush = (entry) => {
908
+ const dir = entry.trim();
909
+ if (dir && path4.win32.isAbsolute(dir) && !/^[\\/](?![\\/])/.test(dir)) dirs.push(dir);
910
+ };
911
+ let current = "";
912
+ let quoted = false;
913
+ for (const c of value) {
914
+ if (c === '"') quoted = !quoted;
915
+ else if (c === ";" && !quoted) {
916
+ flush(current);
917
+ current = "";
918
+ } else current += c;
919
+ }
920
+ if (quoted) for (const entry of current.split(";")) flush(entry);
921
+ else flush(current);
922
+ return dirs;
923
+ }
897
924
 
898
925
  // src/mcp-bin.ts
899
926
  var MCP_PKG = "@yoonion/mimi-seed-mcp";
900
927
  function resolveOnPath(bin, honorForceNpx = true) {
901
928
  if (honorForceNpx && process.env.MIMI_SEED_FORCE_NPX) return null;
902
929
  if (process.platform === "win32") {
903
- const pathKey = Object.keys(process.env).find((key) => key.toLowerCase() === "path");
904
- const directories = (pathKey ? process.env[pathKey] ?? "" : "").split(path4.delimiter).filter(Boolean);
930
+ const directories = absoluteWindowsPathDirs();
905
931
  const names = bin.toLowerCase().endsWith(".cmd") ? [bin] : [`${bin}.cmd`, bin];
906
932
  for (const directory of directories) {
907
933
  for (const name of names) {
908
- const candidate = path4.join(directory.replace(/^"|"$/g, ""), name);
934
+ const candidate = path5.join(directory, name);
909
935
  if (existsSync(candidate)) return candidate;
910
936
  }
911
937
  }
@@ -921,13 +947,13 @@ function resolveWindowsShimTarget(shimPath, source) {
921
947
  const matches = [...source.matchAll(/["']([^"']+\.js)["']\s+%\*/gi)];
922
948
  const raw = matches.at(-1)?.[1];
923
949
  if (!raw) return null;
924
- return path4.win32.normalize(raw.replace(/%~?dp0%?/gi, `${path4.win32.dirname(shimPath)}${path4.win32.sep}`));
950
+ return path5.win32.normalize(raw.replace(/%~?dp0%?/gi, `${path5.win32.dirname(shimPath)}${path5.win32.sep}`));
925
951
  }
926
952
  function npxCliPath(shimPath) {
927
953
  const candidates = [
928
- shimPath ? path4.join(path4.dirname(shimPath), "node_modules", "npm", "bin", "npx-cli.js") : "",
929
- path4.join(path4.dirname(process.execPath), "node_modules", "npm", "bin", "npx-cli.js"),
930
- process.env.npm_execpath ? path4.join(path4.dirname(process.env.npm_execpath), "npx-cli.js") : ""
954
+ shimPath ? path5.join(path5.dirname(shimPath), "node_modules", "npm", "bin", "npx-cli.js") : "",
955
+ path5.join(path5.dirname(process.execPath), "node_modules", "npm", "bin", "npx-cli.js"),
956
+ process.env.npm_execpath ? path5.join(path5.dirname(process.env.npm_execpath), "npx-cli.js") : ""
931
957
  ];
932
958
  return candidates.find((candidate) => candidate && existsSync(candidate)) ?? null;
933
959
  }
@@ -997,12 +1023,12 @@ async function runMcpBin(bin, extraArgs = []) {
997
1023
  // src/jenkins-config.ts
998
1024
  import fs4 from "fs";
999
1025
  import os3 from "os";
1000
- import path6 from "path";
1026
+ import path7 from "path";
1001
1027
 
1002
1028
  // ../core/src/atomic-write.ts
1003
1029
  import { chmodSync, mkdirSync, renameSync, unlinkSync, writeFileSync } from "fs";
1004
1030
  import { randomUUID } from "crypto";
1005
- import path5 from "path";
1031
+ import path6 from "path";
1006
1032
  var CREDENTIAL_FILE_MODE = 384;
1007
1033
  var CREDENTIAL_DIR_MODE = 448;
1008
1034
  var RENAME_RETRY_DELAYS_MS = [10, 20, 40, 80, 160, 320, 370];
@@ -1025,7 +1051,7 @@ function renameWithRetry(from, to, deps = {}) {
1025
1051
  }
1026
1052
  }
1027
1053
  function writeFileAtomic(filePath, contents, options = {}) {
1028
- mkdirSync(path5.dirname(filePath), { recursive: true, ...options.dirMode !== void 0 && { mode: options.dirMode } });
1054
+ mkdirSync(path6.dirname(filePath), { recursive: true, ...options.dirMode !== void 0 && { mode: options.dirMode } });
1029
1055
  const tempPath = `${filePath}.${process.pid}.${randomUUID()}.tmp`;
1030
1056
  try {
1031
1057
  writeFileSync(tempPath, contents, {
@@ -1051,21 +1077,21 @@ function writeCredentialJson(filePath, value) {
1051
1077
  }
1052
1078
 
1053
1079
  // src/jenkins-config.ts
1054
- var CONFIG_DIR = path6.join(os3.homedir(), ".mimi-seed");
1055
- var JENKINS_PATH = path6.join(CONFIG_DIR, "jenkins.json");
1056
- var LEGACY_PATH = path6.join(CONFIG_DIR, "config.json");
1080
+ var CONFIG_DIR = path7.join(os3.homedir(), ".mimi-seed");
1081
+ var JENKINS_PATH = path7.join(CONFIG_DIR, "jenkins.json");
1082
+ var LEGACY_PATH = path7.join(CONFIG_DIR, "config.json");
1057
1083
  function loadJenkinsConfig(home = os3.homedir()) {
1058
1084
  try {
1059
- const p = path6.join(home, ".mimi-seed", "jenkins.json");
1085
+ const p = path7.join(home, ".mimi-seed", "jenkins.json");
1060
1086
  return JSON.parse(fs4.readFileSync(p, "utf-8"));
1061
1087
  } catch {
1062
1088
  return null;
1063
1089
  }
1064
1090
  }
1065
1091
  function migrateLegacyJenkins(home = os3.homedir()) {
1066
- const dir = path6.join(home, ".mimi-seed");
1067
- const jenkinsPath = path6.join(dir, "jenkins.json");
1068
- const legacyPath = path6.join(dir, "config.json");
1092
+ const dir = path7.join(home, ".mimi-seed");
1093
+ const jenkinsPath = path7.join(dir, "jenkins.json");
1094
+ const legacyPath = path7.join(dir, "config.json");
1069
1095
  if (fs4.existsSync(jenkinsPath)) return false;
1070
1096
  let legacy;
1071
1097
  try {
@@ -1091,7 +1117,7 @@ function migrateLegacyJenkins(home = os3.homedir()) {
1091
1117
 
1092
1118
  // src/detect.ts
1093
1119
  import fs5 from "fs/promises";
1094
- import path7 from "path";
1120
+ import path8 from "path";
1095
1121
  async function readIfExists(p) {
1096
1122
  try {
1097
1123
  return await fs5.readFile(p, "utf8");
@@ -1115,9 +1141,9 @@ async function importedJsonObjects(configPath, text, root) {
1115
1141
  ];
1116
1142
  for (const match of imports) {
1117
1143
  if (!match[2].startsWith(".")) continue;
1118
- const candidate = path7.resolve(path7.dirname(configPath), match[2]);
1119
- const relative = path7.relative(root, candidate);
1120
- if (relative.startsWith(`..${path7.sep}`) || relative === ".." || path7.isAbsolute(relative)) continue;
1144
+ const candidate = path8.resolve(path8.dirname(configPath), match[2]);
1145
+ const relative = path8.relative(root, candidate);
1146
+ if (relative.startsWith(`..${path8.sep}`) || relative === ".." || path8.isAbsolute(relative)) continue;
1121
1147
  const jsonText = await readIfExists(candidate);
1122
1148
  if (!jsonText) continue;
1123
1149
  try {
@@ -1161,9 +1187,9 @@ async function walk(root, match, maxDepth = 5) {
1161
1187
  for (const e of entries) {
1162
1188
  if (e.isDirectory()) {
1163
1189
  if (skipDirs.has(e.name)) continue;
1164
- await visit(path7.join(dir, e.name), depth + 1);
1190
+ await visit(path8.join(dir, e.name), depth + 1);
1165
1191
  } else if (e.isFile() && match(e.name)) {
1166
- found.push(path7.join(dir, e.name));
1192
+ found.push(path8.join(dir, e.name));
1167
1193
  }
1168
1194
  }
1169
1195
  }
@@ -1173,7 +1199,7 @@ async function walk(root, match, maxDepth = 5) {
1173
1199
  async function detectHints(cwd) {
1174
1200
  const hints = [];
1175
1201
  for (const fname of ["app.json", "app.config.json"]) {
1176
- const txt = await readIfExists(path7.join(cwd, fname));
1202
+ const txt = await readIfExists(path8.join(cwd, fname));
1177
1203
  if (!txt) continue;
1178
1204
  try {
1179
1205
  const json = JSON.parse(txt);
@@ -1193,7 +1219,7 @@ async function detectHints(cwd) {
1193
1219
  }
1194
1220
  }
1195
1221
  for (const fname of ["app.config.js", "app.config.cjs", "app.config.mjs", "app.config.ts"]) {
1196
- const configPath = path7.join(cwd, fname);
1222
+ const configPath = path8.join(cwd, fname);
1197
1223
  const txt = await readIfExists(configPath);
1198
1224
  if (!txt) continue;
1199
1225
  const imports = await importedJsonObjects(configPath, txt, cwd);
@@ -1215,7 +1241,7 @@ async function detectHints(cwd) {
1215
1241
  if (m?.[1]) {
1216
1242
  const pkg = m[1];
1217
1243
  if (!hints.some((h) => h.packageName === pkg)) {
1218
- hints.push({ packageName: pkg, source: [path7.relative(cwd, f)] });
1244
+ hints.push({ packageName: pkg, source: [path8.relative(cwd, f)] });
1219
1245
  }
1220
1246
  }
1221
1247
  }
@@ -1230,7 +1256,7 @@ async function detectHints(cwd) {
1230
1256
  const bid = m[1];
1231
1257
  if (bid.includes("$(PRODUCT_BUNDLE_IDENTIFIER)")) continue;
1232
1258
  if (!hints.some((h) => h.bundleId === bid)) {
1233
- hints.push({ bundleId: bid, source: [path7.relative(cwd, f)] });
1259
+ hints.push({ bundleId: bid, source: [path8.relative(cwd, f)] });
1234
1260
  }
1235
1261
  }
1236
1262
  }
@@ -1243,11 +1269,11 @@ async function detectHints(cwd) {
1243
1269
  const bid = m[1].trim().replace(/^["']|["']$/g, "");
1244
1270
  if (!bid || bid.includes("$")) continue;
1245
1271
  if (!hints.some((h) => h.bundleId === bid)) {
1246
- hints.push({ bundleId: bid, source: [path7.relative(cwd, f)] });
1272
+ hints.push({ bundleId: bid, source: [path8.relative(cwd, f)] });
1247
1273
  }
1248
1274
  }
1249
1275
  }
1250
- const unitySettings = path7.join(cwd, "ProjectSettings", "ProjectSettings.asset");
1276
+ const unitySettings = path8.join(cwd, "ProjectSettings", "ProjectSettings.asset");
1251
1277
  const unityText = await readIfExists(unitySettings);
1252
1278
  if (unityText) {
1253
1279
  const lines = unityText.split(/\r?\n/);
@@ -1271,11 +1297,11 @@ async function detectHints(cwd) {
1271
1297
  name,
1272
1298
  packageName,
1273
1299
  bundleId,
1274
- source: [path7.relative(cwd, unitySettings)]
1300
+ source: [path8.relative(cwd, unitySettings)]
1275
1301
  });
1276
1302
  }
1277
1303
  }
1278
- const pkgJson = await readIfExists(path7.join(cwd, "package.json"));
1304
+ const pkgJson = await readIfExists(path8.join(cwd, "package.json"));
1279
1305
  if (pkgJson) {
1280
1306
  try {
1281
1307
  const json = JSON.parse(pkgJson);
@@ -1311,7 +1337,7 @@ async function detectHints(cwd) {
1311
1337
  return merged.filter((h) => h.packageName || h.bundleId);
1312
1338
  }
1313
1339
  async function hasAnyProjectSignal(cwd) {
1314
- return await pathExists(path7.join(cwd, "package.json")) || await pathExists(path7.join(cwd, "app.json")) || await pathExists(path7.join(cwd, "android")) || await pathExists(path7.join(cwd, "ios")) || await pathExists(path7.join(cwd, "ProjectSettings", "ProjectSettings.asset"));
1340
+ return await pathExists(path8.join(cwd, "package.json")) || await pathExists(path8.join(cwd, "app.json")) || await pathExists(path8.join(cwd, "android")) || await pathExists(path8.join(cwd, "ios")) || await pathExists(path8.join(cwd, "ProjectSettings", "ProjectSettings.asset"));
1315
1341
  }
1316
1342
 
1317
1343
  // src/deploy.ts
@@ -1321,10 +1347,10 @@ import { randomUUID as randomUUID2 } from "crypto";
1321
1347
 
1322
1348
  // src/config.ts
1323
1349
  import fs6 from "fs/promises";
1324
- import path8 from "path";
1350
+ import path9 from "path";
1325
1351
  import os4 from "os";
1326
- var CONFIG_DIR2 = path8.join(os4.homedir(), ".mimi-seed");
1327
- var CONFIG_PATH = path8.join(CONFIG_DIR2, "config.json");
1352
+ var CONFIG_DIR2 = path9.join(os4.homedir(), ".mimi-seed");
1353
+ var CONFIG_PATH = path9.join(CONFIG_DIR2, "config.json");
1328
1354
  async function readConfig() {
1329
1355
  try {
1330
1356
  const txt = await fs6.readFile(CONFIG_PATH, "utf8");
@@ -1448,7 +1474,7 @@ async function consumeDeployStream(reader, onEvent) {
1448
1474
 
1449
1475
  // src/project-link.ts
1450
1476
  import fs7 from "fs/promises";
1451
- import path9 from "path";
1477
+ import path10 from "path";
1452
1478
 
1453
1479
  // ../core/src/http-errors.ts
1454
1480
  function endpointLabel(input, fallback) {
@@ -1528,9 +1554,9 @@ function isLink(value) {
1528
1554
  return link.schema === 1 && typeof link.webBase === "string" && !!link.webBase && typeof link.appId === "string" && !!link.appId && (link.packageName === void 0 || typeof link.packageName === "string") && (link.bundleId === void 0 || typeof link.bundleId === "string");
1529
1555
  }
1530
1556
  async function findProjectLink(cwd) {
1531
- let dir = path9.resolve(cwd);
1557
+ let dir = path10.resolve(cwd);
1532
1558
  for (let depth = 0; depth <= 8; depth++) {
1533
- const file = path9.join(dir, PROJECT_LINK_FILENAME);
1559
+ const file = path10.join(dir, PROJECT_LINK_FILENAME);
1534
1560
  try {
1535
1561
  const parsed = JSON.parse(await fs7.readFile(file, "utf8"));
1536
1562
  if (!isLink(parsed)) throw new Error(M3().invalidFile);
@@ -1538,7 +1564,7 @@ async function findProjectLink(cwd) {
1538
1564
  } catch (error) {
1539
1565
  if (error.code !== "ENOENT") throw error;
1540
1566
  }
1541
- const parent = path9.dirname(dir);
1567
+ const parent = path10.dirname(dir);
1542
1568
  if (parent === dir) break;
1543
1569
  dir = parent;
1544
1570
  }
@@ -1581,10 +1607,10 @@ async function linkProject(cwd, webBase, token, hint) {
1581
1607
  throw new Error(M3().mismatch);
1582
1608
  }
1583
1609
  if (!existing) {
1584
- await fs7.writeFile(path9.join(cwd, PROJECT_LINK_FILENAME), `${JSON.stringify(link, null, 2)}
1610
+ await fs7.writeFile(path10.join(cwd, PROJECT_LINK_FILENAME), `${JSON.stringify(link, null, 2)}
1585
1611
  `, { mode: 384, flag: "wx" });
1586
1612
  }
1587
- const ignorePath = path9.join(cwd, ".gitignore");
1613
+ const ignorePath = path10.join(cwd, ".gitignore");
1588
1614
  const ignore = await fs7.readFile(ignorePath, "utf8").catch((error) => {
1589
1615
  if (error.code !== "ENOENT") throw error;
1590
1616
  return "";
@@ -1636,7 +1662,7 @@ var M4 = catalog({
1636
1662
 
1637
1663
  // src/jenkins-project.ts
1638
1664
  import fs8 from "fs";
1639
- import path10 from "path";
1665
+ import path11 from "path";
1640
1666
  var M5 = catalog({
1641
1667
  invalidManifest: "\uD504\uB85C\uC81D\uD2B8 .mimi-seed.json\uC740 \uC62C\uBC14\uB978 JSON \uAC1D\uCCB4\uC5EC\uC57C \uD569\uB2C8\uB2E4.",
1642
1668
  controllerMismatch: "\uD504\uB85C\uC81D\uD2B8 Jenkins URL\uACFC \uB85C\uCEEC\uC5D0\uC11C \uC778\uC99D\uB41C \uCEE8\uD2B8\uB864\uB7EC\uAC00 \uB2E4\uB985\uB2C8\uB2E4.",
@@ -1650,9 +1676,9 @@ var M5 = catalog({
1650
1676
  });
1651
1677
  function resolveProjectJenkins(cfg, platform, cwd = process.cwd()) {
1652
1678
  const field = platform === "android" ? "jobAndroid" : "jobIos";
1653
- let dir = path10.resolve(cwd);
1679
+ let dir = path11.resolve(cwd);
1654
1680
  for (let depth = 0; depth <= 8; depth++) {
1655
- const file = path10.join(dir, MANIFEST_FILENAME);
1681
+ const file = path11.join(dir, MANIFEST_FILENAME);
1656
1682
  if (fs8.existsSync(file)) {
1657
1683
  let manifest;
1658
1684
  try {
@@ -1669,7 +1695,7 @@ function resolveProjectJenkins(cfg, platform, cwd = process.cwd()) {
1669
1695
  }
1670
1696
  return { job: validateJob(service?.[field]), source: file };
1671
1697
  }
1672
- const parent = path10.dirname(dir);
1698
+ const parent = path11.dirname(dir);
1673
1699
  if (parent === dir) break;
1674
1700
  dir = parent;
1675
1701
  }
@@ -1706,7 +1732,7 @@ function jenkinsBuildParameters(platform, ref, appId) {
1706
1732
 
1707
1733
  // src/ci-providers.ts
1708
1734
  import fs9 from "fs";
1709
- import path11 from "path";
1735
+ import path12 from "path";
1710
1736
  import os5 from "os";
1711
1737
 
1712
1738
  // ../core/src/ci.ts
@@ -1730,7 +1756,7 @@ function gitlabProjectId(cfg) {
1730
1756
  }
1731
1757
 
1732
1758
  // src/ci-providers.ts
1733
- var CI_CONFIG_PATH = path11.join(os5.homedir(), ".mimi-seed", "ci.json");
1759
+ var CI_CONFIG_PATH = path12.join(os5.homedir(), ".mimi-seed", "ci.json");
1734
1760
  var M6 = catalog(
1735
1761
  {
1736
1762
  badToken: (provider, status) => `${provider} ${status} \u2014 \uD1A0\uD070\uC774 \uC720\uD6A8\uD558\uC9C0 \uC54A\uC544`,
@@ -2565,7 +2591,7 @@ function isLangUnset(home = os6.homedir()) {
2565
2591
  // src/telemetry.ts
2566
2592
  import fs11 from "fs";
2567
2593
  import os7 from "os";
2568
- import path12 from "path";
2594
+ import path13 from "path";
2569
2595
  import { createHmac, randomUUID as randomUUID3 } from "crypto";
2570
2596
  var ENDPOINT = "https://mimi-seed.pryzm.gg/api/sdk-usage";
2571
2597
  var M8 = catalog(
@@ -2582,7 +2608,7 @@ var M8 = catalog(
2582
2608
  invalid: "Usage: mimi-seed telemetry on|off|status\n"
2583
2609
  }
2584
2610
  );
2585
- var location = () => path12.join(os7.homedir(), ".mimi-seed", "telemetry.json");
2611
+ var location = () => path13.join(os7.homedir(), ".mimi-seed", "telemetry.json");
2586
2612
  function readConsent() {
2587
2613
  try {
2588
2614
  return JSON.parse(fs11.readFileSync(location(), "utf8"));
@@ -2615,9 +2641,9 @@ function cmdTelemetry(argv) {
2615
2641
  process.stdout.write(telemetryEnabled() ? M8().enabled : M8().disabled);
2616
2642
  }
2617
2643
  function frameworkAt(root) {
2618
- if (fs11.existsSync(path12.join(root, "ProjectSettings", "ProjectSettings.asset"))) return "unity";
2644
+ if (fs11.existsSync(path13.join(root, "ProjectSettings", "ProjectSettings.asset"))) return "unity";
2619
2645
  try {
2620
- const pkg = JSON.parse(fs11.readFileSync(path12.join(root, "package.json"), "utf8"));
2646
+ const pkg = JSON.parse(fs11.readFileSync(path13.join(root, "package.json"), "utf8"));
2621
2647
  const deps = { ...pkg.dependencies, ...pkg.devDependencies };
2622
2648
  if (deps.expo) return "expo";
2623
2649
  if (deps["react-native"]) return "react-native";
@@ -2633,7 +2659,7 @@ function usageRun(command, projectPath) {
2633
2659
  const installationId = consent.installationId ?? randomUUID3();
2634
2660
  const salt = consent.salt ?? randomUUID3();
2635
2661
  if (!consent.installationId || !consent.salt) writeConsent({ enabled: consent.enabled, installationId, salt });
2636
- let normalized = path12.resolve(projectPath);
2662
+ let normalized = path13.resolve(projectPath);
2637
2663
  try {
2638
2664
  normalized = fs11.realpathSync(normalized);
2639
2665
  } catch {
@@ -2936,6 +2962,7 @@ export {
2936
2962
  detectAll,
2937
2963
  isSatisfied,
2938
2964
  version,
2965
+ absoluteWindowsPathDirs,
2939
2966
  MCP_PKG,
2940
2967
  runMcpBin,
2941
2968
  migrateLegacyJenkins,