mimi-seed 0.2.11 → 0.4.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 +223 -49
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -5,8 +5,8 @@ import {
|
|
|
5
5
|
|
|
6
6
|
// src/index.ts
|
|
7
7
|
import os7 from "os";
|
|
8
|
-
import
|
|
9
|
-
import
|
|
8
|
+
import fs10 from "fs";
|
|
9
|
+
import path10 from "path";
|
|
10
10
|
import kleur9 from "kleur";
|
|
11
11
|
import open from "open";
|
|
12
12
|
|
|
@@ -255,9 +255,9 @@ async function getEffectiveConfig() {
|
|
|
255
255
|
}
|
|
256
256
|
|
|
257
257
|
// src/doctor.ts
|
|
258
|
-
import
|
|
258
|
+
import fs4 from "fs";
|
|
259
259
|
import os2 from "os";
|
|
260
|
-
import
|
|
260
|
+
import path4 from "path";
|
|
261
261
|
import kleur from "kleur";
|
|
262
262
|
|
|
263
263
|
// src/git.ts
|
|
@@ -300,6 +300,33 @@ function formatCommitsForPrompt(commits) {
|
|
|
300
300
|
return commits.map((c) => `- ${c.message} (${c.author}, ${c.date.slice(0, 10)})`).join("\n");
|
|
301
301
|
}
|
|
302
302
|
|
|
303
|
+
// src/project-manifest.ts
|
|
304
|
+
import fs3 from "fs";
|
|
305
|
+
import path3 from "path";
|
|
306
|
+
var MANIFEST_FILENAME = ".mimi-seed.json";
|
|
307
|
+
function findProjectManifest(startDir = process.cwd(), maxDepth = 8) {
|
|
308
|
+
let dir = path3.resolve(startDir);
|
|
309
|
+
for (let i = 0; i <= maxDepth; i++) {
|
|
310
|
+
const candidate = path3.join(dir, MANIFEST_FILENAME);
|
|
311
|
+
if (fs3.existsSync(candidate)) {
|
|
312
|
+
try {
|
|
313
|
+
const obj = JSON.parse(fs3.readFileSync(candidate, "utf-8"));
|
|
314
|
+
if (obj && typeof obj === "object") return { manifest: obj, filePath: candidate };
|
|
315
|
+
} catch {
|
|
316
|
+
}
|
|
317
|
+
return null;
|
|
318
|
+
}
|
|
319
|
+
const parent = path3.dirname(dir);
|
|
320
|
+
if (parent === dir) break;
|
|
321
|
+
dir = parent;
|
|
322
|
+
}
|
|
323
|
+
return null;
|
|
324
|
+
}
|
|
325
|
+
function manifestServiceEntries(m) {
|
|
326
|
+
const svc = m.services ?? {};
|
|
327
|
+
return Object.keys(svc).filter((k) => svc[k] != null).map((k) => [k, svc[k]]);
|
|
328
|
+
}
|
|
329
|
+
|
|
303
330
|
// src/doctor.ts
|
|
304
331
|
function ok(label, detail = "") {
|
|
305
332
|
process.stdout.write(` ${kleur.green("\u2713")} ${label}${detail ? kleur.dim(" " + detail) : ""}
|
|
@@ -317,6 +344,20 @@ function section(title) {
|
|
|
317
344
|
process.stdout.write("\n" + kleur.dim(`\u2500\u2500 ${title} \u2500\u2500
|
|
318
345
|
`));
|
|
319
346
|
}
|
|
347
|
+
function manifestDetail(id, svc) {
|
|
348
|
+
const parts = [];
|
|
349
|
+
if (id === "bigquery") {
|
|
350
|
+
if (svc.projectId) parts.push(svc.projectId);
|
|
351
|
+
if (svc.dataset) parts.push(svc.dataset);
|
|
352
|
+
} else if (id === "playstore" && svc.packageName) {
|
|
353
|
+
parts.push(svc.packageName);
|
|
354
|
+
} else if (id === "appstore" && svc.keyId) {
|
|
355
|
+
parts.push(`keyId ${svc.keyId}`);
|
|
356
|
+
} else if (id === "jenkins" && svc.url) {
|
|
357
|
+
parts.push(svc.url);
|
|
358
|
+
}
|
|
359
|
+
return parts.join(" / ");
|
|
360
|
+
}
|
|
320
361
|
async function cmdDoctor() {
|
|
321
362
|
const cwd = process.cwd();
|
|
322
363
|
process.stdout.write(kleur.bold("mimi-seed doctor\n\n"));
|
|
@@ -339,33 +380,64 @@ async function cmdDoctor() {
|
|
|
339
380
|
}
|
|
340
381
|
}
|
|
341
382
|
section("\uB85C\uCEEC MCP \uC790\uACA9\uC99D\uBA85 (~/.mimi-seed)");
|
|
342
|
-
const credDir =
|
|
343
|
-
const hasFile = (name) =>
|
|
383
|
+
const credDir = path4.join(os2.homedir(), ".mimi-seed");
|
|
384
|
+
const hasFile = (name) => fs4.existsSync(path4.join(credDir, name));
|
|
344
385
|
const hasPrefix = (prefix) => {
|
|
345
386
|
try {
|
|
346
|
-
return
|
|
387
|
+
return fs4.readdirSync(credDir).some((f) => f.startsWith(prefix));
|
|
347
388
|
} catch {
|
|
348
389
|
return false;
|
|
349
390
|
}
|
|
350
391
|
};
|
|
351
392
|
const hasPlaySa = hasFile("play-service-account.json") || (() => {
|
|
352
393
|
try {
|
|
353
|
-
return
|
|
394
|
+
return fs4.readdirSync(path4.join(credDir, "play-service-accounts")).some((f) => f.endsWith(".json"));
|
|
354
395
|
} catch {
|
|
355
396
|
return false;
|
|
356
397
|
}
|
|
357
398
|
})();
|
|
399
|
+
const oauthPresent = hasFile("tokens.json");
|
|
400
|
+
const appstorePresent = hasFile("appstore.json");
|
|
401
|
+
const bigquerySaPresent = hasPrefix("bigquery");
|
|
358
402
|
const creds = [
|
|
359
|
-
["Google OAuth (Firebase/AdMob/Play/Ads)",
|
|
360
|
-
["App Store Connect",
|
|
403
|
+
["Google OAuth (Firebase/AdMob/Play/Ads)", oauthPresent, "mimi-seed auth login"],
|
|
404
|
+
["App Store Connect", appstorePresent, "mimi-seed auth appstore"],
|
|
361
405
|
["Play \uC11C\uBE44\uC2A4 \uACC4\uC815 (\uC120\uD0DD \u2014 OAuth\uB85C\uB3C4 \uAC00\uB2A5)", hasPlaySa, "mimi-seed auth playstore"],
|
|
362
|
-
["BigQuery \uC11C\uBE44\uC2A4 \uACC4\uC815",
|
|
406
|
+
["BigQuery \uC11C\uBE44\uC2A4 \uACC4\uC815", bigquerySaPresent, "mimi-seed auth bigquery"]
|
|
363
407
|
];
|
|
364
408
|
for (const [label, present, cmd] of creds) {
|
|
365
409
|
if (present) ok(label);
|
|
366
410
|
else warn(label, `\u2192 ${cmd}`);
|
|
367
411
|
}
|
|
368
412
|
process.stdout.write(kleur.dim(" OAuth \uD1A0\uD070 \uC2E0\uC120\uB3C4 \uD655\uC778: mimi-seed auth status\n"));
|
|
413
|
+
const loaded = findProjectManifest(cwd);
|
|
414
|
+
if (loaded) {
|
|
415
|
+
const projName = loaded.manifest.displayName ?? loaded.manifest.project ?? "\uC774 \uD504\uB85C\uC81D\uD2B8";
|
|
416
|
+
section(`${projName} \uC694\uAD6C\uC0AC\uD56D (.mimi-seed.json)`);
|
|
417
|
+
const connectedOf = {
|
|
418
|
+
oauth: oauthPresent,
|
|
419
|
+
bigquery: bigquerySaPresent || oauthPresent,
|
|
420
|
+
playstore: hasPlaySa || oauthPresent,
|
|
421
|
+
appstore: appstorePresent,
|
|
422
|
+
jenkins: false
|
|
423
|
+
// mimi-seed 로컬 자격증명 대상 아님(별도 MCP) — note 로만 안내
|
|
424
|
+
};
|
|
425
|
+
const fixOf = {
|
|
426
|
+
oauth: "mimi-seed auth login",
|
|
427
|
+
bigquery: "mimi-seed auth bigquery",
|
|
428
|
+
playstore: "mimi-seed auth playstore",
|
|
429
|
+
appstore: "mimi-seed auth appstore",
|
|
430
|
+
jenkins: "claude mcp add virgm-jenkins -s user"
|
|
431
|
+
};
|
|
432
|
+
for (const [id, svc] of manifestServiceEntries(loaded.manifest)) {
|
|
433
|
+
const required = svc.required !== false;
|
|
434
|
+
const connected = connectedOf[id];
|
|
435
|
+
const detail = manifestDetail(id, svc);
|
|
436
|
+
if (connected) ok(id, detail);
|
|
437
|
+
else if (!required) warn(`${id} (\uC120\uD0DD)`, svc.note ?? detail);
|
|
438
|
+
else fail(id, `\u2192 ${fixOf[id]}${detail ? " " + detail : ""}`);
|
|
439
|
+
}
|
|
440
|
+
}
|
|
369
441
|
section("\uB85C\uCEEC \uD658\uACBD");
|
|
370
442
|
const nodeVer = process.version;
|
|
371
443
|
const [, major] = nodeVer.match(/v(\d+)/) ?? [];
|
|
@@ -837,12 +909,12 @@ async function cmdReview(argv) {
|
|
|
837
909
|
|
|
838
910
|
// src/auth.ts
|
|
839
911
|
import { spawn } from "child_process";
|
|
840
|
-
import
|
|
912
|
+
import fs5 from "fs";
|
|
841
913
|
import os3 from "os";
|
|
842
|
-
import
|
|
914
|
+
import path5 from "path";
|
|
843
915
|
import kleur5 from "kleur";
|
|
844
916
|
var MCP_PKG = "@yoonion/mimi-seed-mcp";
|
|
845
|
-
var MIMI_DIR =
|
|
917
|
+
var MIMI_DIR = path5.join(os3.homedir(), ".mimi-seed");
|
|
846
918
|
function log(msg) {
|
|
847
919
|
process.stdout.write(msg + "\n");
|
|
848
920
|
}
|
|
@@ -886,11 +958,11 @@ async function runMcpBin(bin, extraArgs) {
|
|
|
886
958
|
});
|
|
887
959
|
}
|
|
888
960
|
function fileExists(name) {
|
|
889
|
-
return
|
|
961
|
+
return fs5.existsSync(path5.join(MIMI_DIR, name));
|
|
890
962
|
}
|
|
891
963
|
function anyFileStarting(prefix) {
|
|
892
964
|
try {
|
|
893
|
-
return
|
|
965
|
+
return fs5.readdirSync(MIMI_DIR).some((f) => f.startsWith(prefix));
|
|
894
966
|
} catch {
|
|
895
967
|
return false;
|
|
896
968
|
}
|
|
@@ -949,30 +1021,61 @@ function exitWith(code) {
|
|
|
949
1021
|
if (code !== 0) process.exit(code);
|
|
950
1022
|
}
|
|
951
1023
|
|
|
1024
|
+
// src/cloud.ts
|
|
1025
|
+
import { spawn as spawn2 } from "child_process";
|
|
1026
|
+
var MCP_PKG2 = "@yoonion/mimi-seed-mcp";
|
|
1027
|
+
async function runMcpBin2(bin, extraArgs) {
|
|
1028
|
+
return new Promise((resolve) => {
|
|
1029
|
+
const child = spawn2("npx", ["-y", `${MCP_PKG2}`, bin, ...extraArgs], {
|
|
1030
|
+
stdio: "inherit",
|
|
1031
|
+
shell: true
|
|
1032
|
+
});
|
|
1033
|
+
child.on("error", (e) => {
|
|
1034
|
+
process.stderr.write(`
|
|
1035
|
+
\u274C npx \uC2E4\uD589 \uC2E4\uD328: ${e.message}
|
|
1036
|
+
`);
|
|
1037
|
+
resolve(1);
|
|
1038
|
+
});
|
|
1039
|
+
child.on("exit", (code) => resolve(code ?? 0));
|
|
1040
|
+
});
|
|
1041
|
+
}
|
|
1042
|
+
function exitWith2(code) {
|
|
1043
|
+
if (code !== 0) process.exit(code);
|
|
1044
|
+
}
|
|
1045
|
+
async function cmdFirebase(args) {
|
|
1046
|
+
exitWith2(await runMcpBin2("mimi-seed-firebase", args));
|
|
1047
|
+
}
|
|
1048
|
+
async function cmdAdmob(args) {
|
|
1049
|
+
exitWith2(await runMcpBin2("mimi-seed-admob", args));
|
|
1050
|
+
}
|
|
1051
|
+
async function cmdGa4(args) {
|
|
1052
|
+
exitWith2(await runMcpBin2("mimi-seed-ga4", args));
|
|
1053
|
+
}
|
|
1054
|
+
|
|
952
1055
|
// src/deploy.ts
|
|
953
1056
|
import kleur6 from "kleur";
|
|
954
1057
|
import * as readline from "readline";
|
|
955
1058
|
|
|
956
1059
|
// src/ci-providers.ts
|
|
957
|
-
import
|
|
958
|
-
import
|
|
1060
|
+
import fs6 from "fs";
|
|
1061
|
+
import path6 from "path";
|
|
959
1062
|
import os4 from "os";
|
|
960
|
-
var CI_CONFIG_PATH =
|
|
1063
|
+
var CI_CONFIG_PATH = path6.join(os4.homedir(), ".mimi-seed", "ci.json");
|
|
961
1064
|
function loadCiProviderConfig() {
|
|
962
1065
|
try {
|
|
963
|
-
return JSON.parse(
|
|
1066
|
+
return JSON.parse(fs6.readFileSync(CI_CONFIG_PATH, "utf-8"));
|
|
964
1067
|
} catch {
|
|
965
1068
|
return null;
|
|
966
1069
|
}
|
|
967
1070
|
}
|
|
968
1071
|
function saveCiProviderConfig(cfg) {
|
|
969
|
-
const dir =
|
|
970
|
-
if (!
|
|
971
|
-
|
|
1072
|
+
const dir = path6.dirname(CI_CONFIG_PATH);
|
|
1073
|
+
if (!fs6.existsSync(dir)) {
|
|
1074
|
+
fs6.mkdirSync(dir, { recursive: true, mode: 448 });
|
|
972
1075
|
}
|
|
973
|
-
|
|
1076
|
+
fs6.writeFileSync(CI_CONFIG_PATH, JSON.stringify(cfg, null, 2));
|
|
974
1077
|
if (process.platform !== "win32") {
|
|
975
|
-
|
|
1078
|
+
fs6.chmodSync(CI_CONFIG_PATH, 384);
|
|
976
1079
|
}
|
|
977
1080
|
}
|
|
978
1081
|
function ghBase(cfg) {
|
|
@@ -1473,17 +1576,17 @@ async function cmdDeploy(argv) {
|
|
|
1473
1576
|
|
|
1474
1577
|
// src/mcp-restart.ts
|
|
1475
1578
|
import { execSync as execSync2 } from "child_process";
|
|
1476
|
-
import
|
|
1579
|
+
import fs7 from "fs";
|
|
1477
1580
|
import os5 from "os";
|
|
1478
|
-
import
|
|
1581
|
+
import path7 from "path";
|
|
1479
1582
|
import kleur7 from "kleur";
|
|
1480
1583
|
function log3(msg) {
|
|
1481
1584
|
process.stdout.write(msg + "\n");
|
|
1482
1585
|
}
|
|
1483
1586
|
function readClaudeJson() {
|
|
1484
|
-
const p =
|
|
1587
|
+
const p = path7.join(os5.homedir(), ".claude.json");
|
|
1485
1588
|
try {
|
|
1486
|
-
return JSON.parse(
|
|
1589
|
+
return JSON.parse(fs7.readFileSync(p, "utf8"));
|
|
1487
1590
|
} catch {
|
|
1488
1591
|
return {};
|
|
1489
1592
|
}
|
|
@@ -1570,8 +1673,8 @@ async function cmdRestart(args) {
|
|
|
1570
1673
|
}
|
|
1571
1674
|
|
|
1572
1675
|
// src/mcp-config.ts
|
|
1573
|
-
import
|
|
1574
|
-
import
|
|
1676
|
+
import fs8 from "fs/promises";
|
|
1677
|
+
import path8 from "path";
|
|
1575
1678
|
import os6 from "os";
|
|
1576
1679
|
import kleur8 from "kleur";
|
|
1577
1680
|
var SERVER_NAME = "mimi-seed";
|
|
@@ -1612,20 +1715,63 @@ function printMcpSetup(cfg) {
|
|
|
1612
1715
|
);
|
|
1613
1716
|
}
|
|
1614
1717
|
async function writeCodexMcpConfig(cfg) {
|
|
1615
|
-
const configDir =
|
|
1616
|
-
const configPath =
|
|
1617
|
-
await
|
|
1718
|
+
const configDir = path8.join(os6.homedir(), ".codex");
|
|
1719
|
+
const configPath = path8.join(configDir, "config.toml");
|
|
1720
|
+
await fs8.mkdir(configDir, { recursive: true });
|
|
1618
1721
|
let current = "";
|
|
1619
1722
|
try {
|
|
1620
|
-
current = await
|
|
1723
|
+
current = await fs8.readFile(configPath, "utf8");
|
|
1621
1724
|
} catch {
|
|
1622
1725
|
current = "";
|
|
1623
1726
|
}
|
|
1624
1727
|
const next = replaceTomlBlock(current, `mcp_servers.${SERVER_NAME}`, codexBlock(cfg));
|
|
1625
|
-
await
|
|
1728
|
+
await fs8.writeFile(configPath, next);
|
|
1626
1729
|
return configPath;
|
|
1627
1730
|
}
|
|
1628
1731
|
|
|
1732
|
+
// src/release-manifest.ts
|
|
1733
|
+
import fs9 from "fs/promises";
|
|
1734
|
+
import path9 from "path";
|
|
1735
|
+
var RELEASE_MANIFEST_RELATIVE_PATH = path9.join("docs", "releases.json");
|
|
1736
|
+
var RELEASE_MANIFEST_TEMPLATE = {
|
|
1737
|
+
$schema: {
|
|
1738
|
+
_comment: "Mimi Seed release notes SSOT. Store notes, App Store What's New, in-app announcements, and app-version rollout metadata can share this file.",
|
|
1739
|
+
fields: {
|
|
1740
|
+
date: "ISO 8601 release/build date.",
|
|
1741
|
+
android: "Google Play release notes, 500 characters or fewer per locale.",
|
|
1742
|
+
ios: "App Store What's New, 4000 characters or fewer.",
|
|
1743
|
+
appVersion: {
|
|
1744
|
+
minVersion: "Optional minimum supported app version.",
|
|
1745
|
+
latestVersion: "Optional latest recommended app version.",
|
|
1746
|
+
android: "Optional Android override: { minVersion?, latestVersion? }.",
|
|
1747
|
+
ios: "Optional iOS override: { minVersion?, latestVersion? }."
|
|
1748
|
+
},
|
|
1749
|
+
announcement: {
|
|
1750
|
+
title: "Optional in-app announcement title.",
|
|
1751
|
+
content: "Optional in-app announcement body.",
|
|
1752
|
+
type: "info | update | event | maintenance",
|
|
1753
|
+
pinned: "Optional boolean."
|
|
1754
|
+
},
|
|
1755
|
+
highlights: "Optional internal changelog bullets."
|
|
1756
|
+
}
|
|
1757
|
+
},
|
|
1758
|
+
versions: {}
|
|
1759
|
+
};
|
|
1760
|
+
async function ensureReleaseManifest(cwd) {
|
|
1761
|
+
const filePath = path9.join(cwd, RELEASE_MANIFEST_RELATIVE_PATH);
|
|
1762
|
+
try {
|
|
1763
|
+
await fs9.access(filePath);
|
|
1764
|
+
return { path: filePath, created: false };
|
|
1765
|
+
} catch {
|
|
1766
|
+
}
|
|
1767
|
+
await fs9.mkdir(path9.dirname(filePath), { recursive: true });
|
|
1768
|
+
await fs9.writeFile(filePath, `${JSON.stringify(RELEASE_MANIFEST_TEMPLATE, null, 2)}
|
|
1769
|
+
`, {
|
|
1770
|
+
mode: 420
|
|
1771
|
+
});
|
|
1772
|
+
return { path: filePath, created: true };
|
|
1773
|
+
}
|
|
1774
|
+
|
|
1629
1775
|
// src/index.ts
|
|
1630
1776
|
var DEFAULT_WEB_BASE = process.env.MIMI_SEED_WEB_BASE ?? "https://mimi-seed.pryzm.gg";
|
|
1631
1777
|
var DEFAULT_MCP_ENDPOINT = `${DEFAULT_WEB_BASE}/api/mcp`;
|
|
@@ -1664,6 +1810,8 @@ async function cmdInit(args) {
|
|
|
1664
1810
|
for (const line of result.text.split("\n")) log4(" " + line);
|
|
1665
1811
|
}
|
|
1666
1812
|
}
|
|
1813
|
+
const manifest2 = await ensureReleaseManifest(cwd);
|
|
1814
|
+
log4(kleur9.dim(` \uB9B4\uB9AC\uC988 \uB178\uD2B8 SSOT: ${manifest2.created ? "\uC0DD\uC131" : "\uD655\uC778"} docs/releases.json`));
|
|
1667
1815
|
log4(kleur9.bold("\u2713 \uC644\uB8CC (CI \uBAA8\uB4DC)"));
|
|
1668
1816
|
return;
|
|
1669
1817
|
}
|
|
@@ -1718,12 +1866,24 @@ async function cmdInit(args) {
|
|
|
1718
1866
|
"Mimi Seed MCP\uAC00 \uC774 \uD504\uB85C\uC81D\uD2B8\uC5D0 \uC5F0\uACB0\uB418\uC5B4 \uC788\uC2B5\uB2C8\uB2E4.",
|
|
1719
1867
|
"Google Play \xB7 App Store \xB7 Firebase \xB7 AdMob\uC744 \uB3C4\uAD6C\uB85C \uC9C1\uC811 \uC81C\uC5B4\uD569\uB2C8\uB2E4.",
|
|
1720
1868
|
"",
|
|
1869
|
+
"## \uC138\uC158 \uC2DC\uC791",
|
|
1870
|
+
"",
|
|
1871
|
+
"1. \uCD9C\uC2DC/\uC2A4\uD1A0\uC5B4/Firebase/AdMob \uC694\uCCAD\uC740 \uBA3C\uC800 `mimi_seed_status`\uB85C \uC5F0\uACB0 \uC0C1\uD0DC\uB97C \uD655\uC778",
|
|
1872
|
+
"2. \uC778\uC99D \uB204\uB77D\uC774\uBA74 `mimi_seed_auth_start` \uB610\uB294 \uC544\uB798 \uB85C\uCEEC \uC778\uC99D \uBA85\uB839\uC744 \uC548\uB0B4",
|
|
1873
|
+
'3. Claude Code\uC5D0\uC11C \uB3C4\uAD6C schema\uAC00 deferred \uC0C1\uD0DC\uB77C\uBA74 \uD544\uC694\uD55C \uB3C4\uAD6C\uB97C `ToolSearch(query="select:<tool>[,<tool>...]")`\uB85C \uBA3C\uC800 \uB85C\uB4DC',
|
|
1874
|
+
"",
|
|
1721
1875
|
"## \uCD9C\uC2DC \uC694\uCCAD \uCC98\uB9AC \uC21C\uC11C",
|
|
1722
1876
|
"",
|
|
1723
|
-
"1. \uD56D\uC0C1 `playstore_check_submission_risks` / `appstore_check_submission_risks` \uB85C \uBE14\uB85C\uCEE4 \
|
|
1724
|
-
"2. \uB9B4\uB9AC\uC988 \uB178\uD2B8
|
|
1725
|
-
"3. \uC2A4\uD1A0\uC5B4 **\uC4F0\uAE30** \uC791\uC5C5(submit, apply, reply)\uC740 \uBC18\uB4DC\uC2DC \uC0AC\uC6A9\uC790 \uBA85\uC2DC \uB3D9\uC758 \uD6C4 \uC2E4\uD589",
|
|
1726
|
-
"4. \uC644\uB8CC \uD6C4 \uACB0\uACFC \
|
|
1877
|
+
"1. \uD56D\uC0C1 `playstore_check_submission_risks` / `appstore_check_submission_risks` \uB85C \uBE14\uB85C\uCEE4 \uD655\uC778",
|
|
1878
|
+
"2. \uB9B4\uB9AC\uC988 \uB178\uD2B8\uB294 `docs/releases.json`\uC744 SSOT\uB85C \uD655\uC778/\uC791\uC131 \u2192 \uC0AC\uC6A9\uC790 \uD655\uC778 \uD6C4 \uC801\uC6A9",
|
|
1879
|
+
"3. \uC2A4\uD1A0\uC5B4 **\uC4F0\uAE30** \uC791\uC5C5(submit, apply, reply, delete)\uC740 \uBC18\uB4DC\uC2DC \uC0AC\uC6A9\uC790 \uBA85\uC2DC \uB3D9\uC758 \uD6C4 \uC2E4\uD589",
|
|
1880
|
+
"4. \uCD9C\uC2DC \uC644\uB8CC \uD6C4 \uC801\uC6A9 \uACB0\uACFC\uC640 \uC2E4\uD328 \uC9C0\uC810 \uC694\uC57D",
|
|
1881
|
+
"",
|
|
1882
|
+
"## \uC778\uC99D \uBCF5\uAD6C",
|
|
1883
|
+
"",
|
|
1884
|
+
"- Google/Firebase/AdMob/Play OAuth: `npx -y @yoonion/mimi-seed-mcp mimi-seed-auth`",
|
|
1885
|
+
"- App Store Connect: `npx -y @yoonion/mimi-seed-mcp mimi-seed-appstore-auth`",
|
|
1886
|
+
"- Play service account: `npx -y @yoonion/mimi-seed-mcp mimi-seed-playstore-auth`",
|
|
1727
1887
|
"",
|
|
1728
1888
|
"## \uC571 \uC815\uBCF4",
|
|
1729
1889
|
...appLines.length > 0 ? appLines : [" (mimi-seed status \uB85C \uD655\uC778)"],
|
|
@@ -1734,18 +1894,20 @@ async function cmdInit(args) {
|
|
|
1734
1894
|
"- `/mimi-seed:health` \u2014 \uC5F0\uACB0 \uC0C1\uD0DC \uBE60\uB978 \uD655\uC778",
|
|
1735
1895
|
"- `/mimi-seed:review-inbox` \u2014 \uBBF8\uB2F5\uBCC0 \uB9AC\uBDF0 \uB2F5\uBCC0"
|
|
1736
1896
|
].join("\n");
|
|
1737
|
-
const claudeDir =
|
|
1738
|
-
const claudeAgentPath =
|
|
1739
|
-
if (!
|
|
1740
|
-
|
|
1741
|
-
|
|
1897
|
+
const claudeDir = path10.join(cwd, ".claude");
|
|
1898
|
+
const claudeAgentPath = path10.join(claudeDir, "mimi-seed.md");
|
|
1899
|
+
if (!fs10.existsSync(claudeAgentPath)) {
|
|
1900
|
+
fs10.mkdirSync(claudeDir, { recursive: true });
|
|
1901
|
+
fs10.writeFileSync(claudeAgentPath, agentMd, { mode: 420 });
|
|
1742
1902
|
log4(kleur9.dim(` Claude \uC5D0\uC774\uC804\uD2B8 \uC124\uC815: .claude/mimi-seed.md`));
|
|
1743
1903
|
}
|
|
1744
|
-
const codexAgentPath =
|
|
1745
|
-
if (!
|
|
1746
|
-
|
|
1904
|
+
const codexAgentPath = path10.join(cwd, "AGENTS.md");
|
|
1905
|
+
if (!fs10.existsSync(codexAgentPath)) {
|
|
1906
|
+
fs10.writeFileSync(codexAgentPath, agentMd, { mode: 420 });
|
|
1747
1907
|
log4(kleur9.dim(` Codex \uC5D0\uC774\uC804\uD2B8 \uC124\uC815: AGENTS.md`));
|
|
1748
1908
|
}
|
|
1909
|
+
const manifest = await ensureReleaseManifest(cwd);
|
|
1910
|
+
log4(kleur9.dim(` \uB9B4\uB9AC\uC988 \uB178\uD2B8 SSOT: ${manifest.created ? "\uC0DD\uC131" : "\uD655\uC778"} docs/releases.json`));
|
|
1749
1911
|
log4(kleur9.bold("\u2713 \uC900\uBE44 \uC644\uB8CC."));
|
|
1750
1912
|
log4("");
|
|
1751
1913
|
log4("Claude Code \uB610\uB294 Codex\uC5D0\uC11C \uC774\uB807\uAC8C \uBB3C\uC5B4\uBCF4\uC138\uC694:");
|
|
@@ -1833,7 +1995,7 @@ var CMD_USAGE = {
|
|
|
1833
1995
|
init: `${kleur9.bold("mimi-seed init")} \u2014 \uD604\uC7AC \uD504\uB85C\uC81D\uD2B8\uB97C Mimi Seed\uC5D0 \uC5F0\uACB0
|
|
1834
1996
|
|
|
1835
1997
|
\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
|
|
1836
|
-
+ .claude/mimi-seed.md, AGENTS.md \uC0DD\uC131.
|
|
1998
|
+
+ .claude/mimi-seed.md, AGENTS.md, docs/releases.json \uC0DD\uC131/\uD655\uC778.
|
|
1837
1999
|
|
|
1838
2000
|
\uC635\uC158:
|
|
1839
2001
|
--local \uCD94\uAC00\uB85C Google OAuth \uB85C\uADF8\uC778 + \uB85C\uCEEC 110+ tool MCP \uB4F1\uB85D \uC548\uB0B4`,
|
|
@@ -1906,6 +2068,9 @@ ${kleur9.bold("\uBA85\uB839\uC5B4:")}
|
|
|
1906
2068
|
${kleur9.cyan("mimi-seed init")} \uD604\uC7AC \uD504\uB85C\uC81D\uD2B8\uB97C Mimi Seed\uC5D0 \uC5F0\uACB0
|
|
1907
2069
|
${kleur9.cyan("mimi-seed status")} \uC5F0\uACB0 \uC0C1\uD0DC + \uB4F1\uB85D \uC571 \uBAA9\uB85D
|
|
1908
2070
|
${kleur9.cyan("mimi-seed auth")} \uB85C\uCEEC \uC778\uC99D (Google OAuth / App Store / Play / BigQuery)
|
|
2071
|
+
${kleur9.cyan("mimi-seed firebase")} Firebase \uC571 \uC0DD\uC131\xB7config \uB2E4\uC6B4\uB85C\uB4DC\xB7GA4 \uB9C1\uD06C
|
|
2072
|
+
${kleur9.cyan("mimi-seed admob")} AdMob \uACC4\uC815\xB7\uC571\xB7\uAD11\uACE0\uB2E8\uC704 \uC870\uD68C \uBC0F \uC0DD\uC131
|
|
2073
|
+
${kleur9.cyan("mimi-seed ga4")} GA4 property\xB7data stream \uC0DD\uC131\xB7\uC870\uD68C
|
|
1909
2074
|
${kleur9.cyan("mimi-seed doctor")} \uD658\uACBD \uC9C4\uB2E8 (\uD1A0\uD070\xB7Git\xB7\uD504\uB85C\uC81D\uD2B8\xB7CI \uCCB4\uD06C)
|
|
1910
2075
|
${kleur9.cyan("mimi-seed check")} \uCD9C\uC2DC \uC804 Readiness \uC810\uAC80
|
|
1911
2076
|
${kleur9.cyan("mimi-seed notes")} \uB9B4\uB9AC\uC988 \uB178\uD2B8 \uC0DD\uC131 (git log \u2192 AI \u2192 \uB9C8\uCF13 \uC801\uC6A9)
|
|
@@ -1952,6 +2117,15 @@ async function main() {
|
|
|
1952
2117
|
case "auth":
|
|
1953
2118
|
await cmdAuth(restArgs);
|
|
1954
2119
|
break;
|
|
2120
|
+
case "firebase":
|
|
2121
|
+
await cmdFirebase(restArgs);
|
|
2122
|
+
break;
|
|
2123
|
+
case "admob":
|
|
2124
|
+
await cmdAdmob(restArgs);
|
|
2125
|
+
break;
|
|
2126
|
+
case "ga4":
|
|
2127
|
+
await cmdGa4(restArgs);
|
|
2128
|
+
break;
|
|
1955
2129
|
case "deploy":
|
|
1956
2130
|
await cmdDeploy(restArgs);
|
|
1957
2131
|
break;
|