mimi-seed 0.19.11 → 0.19.13
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 +37 -373
- package/dist/{chunk-UKNCSE4V.js → chunk-YIVIN2XR.js} +715 -213
- package/dist/index.js +232 -173
- package/dist/{setup-VO5WN32U.js → setup-Z34QP6PO.js} +1 -2
- package/package.json +3 -2
- package/dist/chunk-2FKWHED2.js +0 -56
- package/dist/chunk-TQHLWSFR.js +0 -260
- package/dist/mcp-client-L5BQ5VG4.js +0 -8
package/dist/index.js
CHANGED
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import {
|
|
3
|
-
mcpCall
|
|
4
|
-
} from "./chunk-2FKWHED2.js";
|
|
5
2
|
import {
|
|
6
3
|
CONFIG_LOCATION,
|
|
7
4
|
CREDENTIALS,
|
|
8
5
|
MCP_PKG,
|
|
6
|
+
catalog,
|
|
9
7
|
cmdDeploy,
|
|
10
8
|
cmdSetup,
|
|
9
|
+
cmdTelemetry,
|
|
11
10
|
credLabel,
|
|
12
11
|
credNote,
|
|
13
12
|
deleteConfig,
|
|
@@ -16,20 +15,19 @@ import {
|
|
|
16
15
|
findProjectManifest,
|
|
17
16
|
getEffectiveConfig,
|
|
18
17
|
hasAnyProjectSignal,
|
|
18
|
+
isLang,
|
|
19
19
|
isSatisfied,
|
|
20
20
|
manifestServiceEntries,
|
|
21
21
|
migrateLegacyJenkins,
|
|
22
|
-
runMcpBin,
|
|
23
|
-
tryCredById,
|
|
24
|
-
writeConfig
|
|
25
|
-
} from "./chunk-UKNCSE4V.js";
|
|
26
|
-
import {
|
|
27
|
-
catalog,
|
|
28
|
-
isLang,
|
|
29
22
|
resolveLang,
|
|
23
|
+
runMcpBin,
|
|
30
24
|
t,
|
|
25
|
+
telemetryNotice,
|
|
26
|
+
tryCredById,
|
|
27
|
+
usageRun,
|
|
28
|
+
writeConfig,
|
|
31
29
|
writeSettings
|
|
32
|
-
} from "./chunk-
|
|
30
|
+
} from "./chunk-YIVIN2XR.js";
|
|
33
31
|
|
|
34
32
|
// src/index.ts
|
|
35
33
|
import os3 from "os";
|
|
@@ -102,6 +100,54 @@ async function awaitHandshake(timeoutMs) {
|
|
|
102
100
|
return { port, promise };
|
|
103
101
|
}
|
|
104
102
|
|
|
103
|
+
// src/mcp-client.ts
|
|
104
|
+
var M2 = catalog(
|
|
105
|
+
{ noSseData: "MCP SSE \uC751\uB2F5\uC5D0 data \uC5C6\uC74C" },
|
|
106
|
+
{ noSseData: "No data in the MCP SSE response" }
|
|
107
|
+
);
|
|
108
|
+
async function mcpCall(endpoint, token, name, args) {
|
|
109
|
+
const res = await fetch(endpoint, {
|
|
110
|
+
method: "POST",
|
|
111
|
+
headers: {
|
|
112
|
+
"Content-Type": "application/json",
|
|
113
|
+
Accept: "application/json, text/event-stream",
|
|
114
|
+
Authorization: `Bearer ${token}`
|
|
115
|
+
},
|
|
116
|
+
body: JSON.stringify({
|
|
117
|
+
jsonrpc: "2.0",
|
|
118
|
+
id: 1,
|
|
119
|
+
method: "tools/call",
|
|
120
|
+
params: { name, arguments: args }
|
|
121
|
+
})
|
|
122
|
+
});
|
|
123
|
+
if (!res.ok) {
|
|
124
|
+
const raw = await res.text();
|
|
125
|
+
let msg = raw;
|
|
126
|
+
try {
|
|
127
|
+
const parsed = JSON.parse(raw);
|
|
128
|
+
if (typeof parsed.error === "string") msg = parsed.error;
|
|
129
|
+
} catch {
|
|
130
|
+
}
|
|
131
|
+
return { text: `HTTP ${res.status}: ${msg}`, isError: true };
|
|
132
|
+
}
|
|
133
|
+
const contentType = res.headers.get("content-type") ?? "";
|
|
134
|
+
let payload;
|
|
135
|
+
if (contentType.includes("text/event-stream")) {
|
|
136
|
+
const text2 = await res.text();
|
|
137
|
+
const line = text2.split("\n").map((l) => l.trim()).find((l) => l.startsWith("data:"));
|
|
138
|
+
if (!line) throw new Error(M2().noSseData);
|
|
139
|
+
payload = JSON.parse(line.slice(5).trim());
|
|
140
|
+
} else {
|
|
141
|
+
payload = await res.json();
|
|
142
|
+
}
|
|
143
|
+
if (payload.error) {
|
|
144
|
+
return { text: payload.error.message, isError: true };
|
|
145
|
+
}
|
|
146
|
+
const content = payload.result?.content ?? [];
|
|
147
|
+
const text = content.filter((c) => c.type === "text").map((c) => c.text ?? "").join("\n");
|
|
148
|
+
return { text, isError: payload.result?.isError ?? false };
|
|
149
|
+
}
|
|
150
|
+
|
|
105
151
|
// src/doctor.ts
|
|
106
152
|
import kleur from "kleur";
|
|
107
153
|
|
|
@@ -1251,7 +1297,7 @@ async function scanReleaseDoctor(projectPath, now = /* @__PURE__ */ new Date())
|
|
|
1251
1297
|
}
|
|
1252
1298
|
|
|
1253
1299
|
// src/check.ts
|
|
1254
|
-
var
|
|
1300
|
+
var M3 = catalog(
|
|
1255
1301
|
{
|
|
1256
1302
|
noAccount: "\uC5F0\uACB0\uB41C \uACC4\uC815 \uC5C6\uC74C. `mimi-seed init` \uC2E4\uD589.\n",
|
|
1257
1303
|
missingOptionValue: (option) => `${option} \uB4A4\uC5D0 \uAC12\uC744 \uC785\uB825\uD558\uC138\uC694.`,
|
|
@@ -1261,6 +1307,7 @@ var M2 = catalog(
|
|
|
1261
1307
|
localFailed: (message) => `Release Doctor \uC2E4\uD589 \uC2E4\uD328: ${message}
|
|
1262
1308
|
`,
|
|
1263
1309
|
title: "mimi-seed check \u2014 \uCD9C\uC2DC \uC804 \uC810\uAC80\n\n",
|
|
1310
|
+
localNext: "\n\uC2A4\uD1A0\uC5B4 \uAC80\uC0AC \uC5F0\uACB0: npx mimi-seed init\nCI\uC5D0\uC11C \uBC18\uBCF5 \uAC80\uC0AC: npx mimi-seed check --local --fail-on-blocker\n",
|
|
1264
1311
|
appsFailed: (msg) => `\uC571 \uBAA9\uB85D \uC870\uD68C \uC2E4\uD328: ${msg}
|
|
1265
1312
|
`,
|
|
1266
1313
|
noApps: "\uB4F1\uB85D\uB41C \uC571\uC774 \uC5C6\uC2B5\uB2C8\uB2E4. `mimi-seed init` \uD6C4 \uC571\uC744 \uB4F1\uB85D\uD558\uC138\uC694.\n",
|
|
@@ -1298,6 +1345,7 @@ var M2 = catalog(
|
|
|
1298
1345
|
localFailed: (message) => `Release Doctor failed: ${message}
|
|
1299
1346
|
`,
|
|
1300
1347
|
title: "mimi-seed check \u2014 pre-launch check\n\n",
|
|
1348
|
+
localNext: "\nConnect store checks: npx mimi-seed init\nRun in CI: npx mimi-seed check --local --fail-on-blocker\n",
|
|
1301
1349
|
appsFailed: (msg) => `Failed to list apps: ${msg}
|
|
1302
1350
|
`,
|
|
1303
1351
|
noApps: "No apps registered. Run `mimi-seed init`, then register an app.\n",
|
|
@@ -1337,7 +1385,7 @@ function parseCheckArgs(argv) {
|
|
|
1337
1385
|
};
|
|
1338
1386
|
const takeValue = (option, index) => {
|
|
1339
1387
|
const value = argv[index + 1];
|
|
1340
|
-
if (!value || value.startsWith("--")) throw new Error(
|
|
1388
|
+
if (!value || value.startsWith("--")) throw new Error(M3().missingOptionValue(option));
|
|
1341
1389
|
return value;
|
|
1342
1390
|
};
|
|
1343
1391
|
for (let i = 0; i < argv.length; i++) {
|
|
@@ -1349,8 +1397,8 @@ function parseCheckArgs(argv) {
|
|
|
1349
1397
|
} else if (token === "--fail-on-blocker") args.failOnBlocker = true;
|
|
1350
1398
|
else if (token === "--local") args.local = true;
|
|
1351
1399
|
else if (token === "--json") args.json = true;
|
|
1352
|
-
else if (token.startsWith("-")) throw new Error(
|
|
1353
|
-
else throw new Error(
|
|
1400
|
+
else if (token.startsWith("-")) throw new Error(M3().unknownOption(token));
|
|
1401
|
+
else throw new Error(M3().unexpectedArgument(token));
|
|
1354
1402
|
}
|
|
1355
1403
|
return args;
|
|
1356
1404
|
}
|
|
@@ -1379,31 +1427,35 @@ async function cmdCheck(argv) {
|
|
|
1379
1427
|
const cfg = await getEffectiveConfig();
|
|
1380
1428
|
const localRequested = args.local || args.json || args.projectPathExplicit;
|
|
1381
1429
|
if (args.appId && localRequested) {
|
|
1382
|
-
process.stderr.write(kleur2.red(
|
|
1430
|
+
process.stderr.write(kleur2.red(M3().localAppConflict));
|
|
1383
1431
|
process.exitCode = 2;
|
|
1384
1432
|
return;
|
|
1385
1433
|
}
|
|
1386
1434
|
if (args.appId && !cfg) {
|
|
1387
|
-
process.stderr.write(kleur2.red(
|
|
1435
|
+
process.stderr.write(kleur2.red(M3().noAccount));
|
|
1388
1436
|
process.exitCode = 1;
|
|
1389
1437
|
return;
|
|
1390
1438
|
}
|
|
1391
1439
|
if (localRequested || !cfg) {
|
|
1440
|
+
const finish = usageRun("check", args.projectPath);
|
|
1392
1441
|
try {
|
|
1393
1442
|
const report = await scanReleaseDoctor(args.projectPath);
|
|
1394
1443
|
process.stdout.write(args.json ? `${JSON.stringify(report, null, 2)}
|
|
1395
1444
|
` : renderReleaseDoctor(report, resolveLang()));
|
|
1445
|
+
if (!args.json && !process.env.CI) process.stdout.write(M3().localNext + telemetryNotice());
|
|
1396
1446
|
if (args.failOnBlocker && report.counts.blocker > 0) process.exitCode = 1;
|
|
1447
|
+
await finish("completed", report);
|
|
1397
1448
|
} catch (error) {
|
|
1398
|
-
process.stderr.write(kleur2.red(
|
|
1449
|
+
process.stderr.write(kleur2.red(M3().localFailed(error instanceof Error ? error.message : String(error))));
|
|
1399
1450
|
process.exitCode = 2;
|
|
1451
|
+
await finish("failed");
|
|
1400
1452
|
}
|
|
1401
1453
|
return;
|
|
1402
1454
|
}
|
|
1403
|
-
process.stdout.write(kleur2.bold(
|
|
1455
|
+
process.stdout.write(kleur2.bold(M3().title));
|
|
1404
1456
|
const appsResult = await mcpCall(cfg.endpoint, cfg.token, "list_apps", {});
|
|
1405
1457
|
if (appsResult.isError) {
|
|
1406
|
-
process.stdout.write(kleur2.red(
|
|
1458
|
+
process.stdout.write(kleur2.red(M3().appsFailed(appsResult.text)));
|
|
1407
1459
|
process.exit(1);
|
|
1408
1460
|
}
|
|
1409
1461
|
let appId = args.appId;
|
|
@@ -1411,29 +1463,29 @@ async function cmdCheck(argv) {
|
|
|
1411
1463
|
try {
|
|
1412
1464
|
const apps = JSON.parse(appsResult.text);
|
|
1413
1465
|
if (!Array.isArray(apps) || apps.length === 0) {
|
|
1414
|
-
process.stdout.write(kleur2.yellow(
|
|
1466
|
+
process.stdout.write(kleur2.yellow(M3().noApps));
|
|
1415
1467
|
process.exit(0);
|
|
1416
1468
|
}
|
|
1417
1469
|
appId = apps[0].id;
|
|
1418
|
-
process.stdout.write(kleur2.dim(
|
|
1470
|
+
process.stdout.write(kleur2.dim(M3().app(apps[0].name ?? appId)));
|
|
1419
1471
|
} catch {
|
|
1420
|
-
process.stdout.write(kleur2.red(
|
|
1472
|
+
process.stdout.write(kleur2.red(M3().appsParseFailed(appsResult.text.slice(0, 80))));
|
|
1421
1473
|
process.exit(1);
|
|
1422
1474
|
}
|
|
1423
1475
|
}
|
|
1424
|
-
process.stdout.write(
|
|
1476
|
+
process.stdout.write(M3().scoring);
|
|
1425
1477
|
const readinessResult = await mcpCall(cfg.endpoint, cfg.token, "get_readiness", { app_id: appId });
|
|
1426
1478
|
if (readinessResult.isError) {
|
|
1427
|
-
process.stdout.write(kleur2.red(
|
|
1479
|
+
process.stdout.write(kleur2.red(M3().scoreFailed(readinessResult.text)));
|
|
1428
1480
|
process.exit(1);
|
|
1429
1481
|
}
|
|
1430
1482
|
let hasBlocker = false;
|
|
1431
1483
|
try {
|
|
1432
1484
|
const data = JSON.parse(readinessResult.text);
|
|
1433
1485
|
const score = data.score ?? 0;
|
|
1434
|
-
process.stdout.write(
|
|
1486
|
+
process.stdout.write(M3().score(renderScore(score)));
|
|
1435
1487
|
if (data.modules) {
|
|
1436
|
-
process.stdout.write(kleur2.dim(
|
|
1488
|
+
process.stdout.write(kleur2.dim(M3().byModule));
|
|
1437
1489
|
for (const [key, val] of Object.entries(data.modules)) {
|
|
1438
1490
|
const label = MODULE_LABELS[key] ?? key;
|
|
1439
1491
|
const color = val >= 25 ? kleur2.green : val >= 10 ? kleur2.yellow : kleur2.red;
|
|
@@ -1444,13 +1496,13 @@ async function cmdCheck(argv) {
|
|
|
1444
1496
|
}
|
|
1445
1497
|
if (data.blockers?.length) {
|
|
1446
1498
|
hasBlocker = true;
|
|
1447
|
-
process.stdout.write(kleur2.bold(
|
|
1499
|
+
process.stdout.write(kleur2.bold(M3().blockers));
|
|
1448
1500
|
for (const b of data.blockers) process.stdout.write(` ${kleur2.red("\u2022")} ${b}
|
|
1449
1501
|
`);
|
|
1450
1502
|
process.stdout.write("\n");
|
|
1451
1503
|
}
|
|
1452
1504
|
if (data.warnings?.length) {
|
|
1453
|
-
process.stdout.write(kleur2.bold(
|
|
1505
|
+
process.stdout.write(kleur2.bold(M3().warnings));
|
|
1454
1506
|
for (const w of data.warnings) process.stdout.write(` ${kleur2.yellow("\u2022")} ${w}
|
|
1455
1507
|
`);
|
|
1456
1508
|
process.stdout.write("\n");
|
|
@@ -1458,19 +1510,19 @@ async function cmdCheck(argv) {
|
|
|
1458
1510
|
const base = `${cfg.webBase}/apps/${appId}`;
|
|
1459
1511
|
const nextSteps = [];
|
|
1460
1512
|
if (data.modules) {
|
|
1461
|
-
if ((data.modules.integration ?? 25) < 25) nextSteps.push(
|
|
1462
|
-
if ((data.modules.copy ?? 25) < 25) nextSteps.push(
|
|
1463
|
-
if ((data.modules.screenshot ?? 25) < 25) nextSteps.push(
|
|
1464
|
-
if ((data.modules.checklist ?? 25) < 25) nextSteps.push(
|
|
1513
|
+
if ((data.modules.integration ?? 25) < 25) nextSteps.push(M3().stepIntegration(`${base}/integration`));
|
|
1514
|
+
if ((data.modules.copy ?? 25) < 25) nextSteps.push(M3().stepCopy(`${base}/copy`));
|
|
1515
|
+
if ((data.modules.screenshot ?? 25) < 25) nextSteps.push(M3().stepScreenshot(`${base}/screenshots`));
|
|
1516
|
+
if ((data.modules.checklist ?? 25) < 25) nextSteps.push(M3().stepChecklist(`${base}/launch`));
|
|
1465
1517
|
}
|
|
1466
1518
|
if (nextSteps.length) {
|
|
1467
|
-
process.stdout.write(kleur2.bold(
|
|
1519
|
+
process.stdout.write(kleur2.bold(M3().nextSteps));
|
|
1468
1520
|
for (const s of nextSteps) process.stdout.write(` ${kleur2.cyan("\u2022")} ${s}
|
|
1469
1521
|
`);
|
|
1470
|
-
process.stdout.write(kleur2.dim(
|
|
1522
|
+
process.stdout.write(kleur2.dim(M3().preview));
|
|
1471
1523
|
}
|
|
1472
1524
|
if (!hasBlocker) {
|
|
1473
|
-
process.stdout.write(score >= 80 ? kleur2.green(
|
|
1525
|
+
process.stdout.write(score >= 80 ? kleur2.green(M3().ready) : kleur2.yellow(M3().notReady(score)));
|
|
1474
1526
|
}
|
|
1475
1527
|
} catch {
|
|
1476
1528
|
for (const line of readinessResult.text.split("\n")) process.stdout.write(" " + line + "\n");
|
|
@@ -1487,7 +1539,7 @@ import kleur3 from "kleur";
|
|
|
1487
1539
|
var CLI_AI_MODEL = "claude-haiku-4-5-20251001";
|
|
1488
1540
|
|
|
1489
1541
|
// src/notes.ts
|
|
1490
|
-
var
|
|
1542
|
+
var M4 = catalog(
|
|
1491
1543
|
{
|
|
1492
1544
|
// Claude 프롬프트
|
|
1493
1545
|
localeHint: (l) => `"${l}": "\uD574\uB2F9 \uC5B8\uC5B4\uB85C \uBC88\uC5ED\uB41C \uAC04\uACB0\uD55C \uBC84\uC804"`,
|
|
@@ -1623,21 +1675,21 @@ async function promptUser(question) {
|
|
|
1623
1675
|
}
|
|
1624
1676
|
async function generateWithClaude(commitsText, locales) {
|
|
1625
1677
|
const client = new Anthropic({ apiKey: process.env.ANTHROPIC_API_KEY });
|
|
1626
|
-
const localeList = locales.map((l) =>
|
|
1678
|
+
const localeList = locales.map((l) => M4().localeHint(l)).join(",\n ");
|
|
1627
1679
|
const response = await client.messages.create({
|
|
1628
1680
|
model: CLI_AI_MODEL,
|
|
1629
1681
|
// mcp-server 의 generateReleaseNotes 기본값과 같아야 한다 — 낮으면 다국어 JSON 이
|
|
1630
1682
|
// CLI 경로에서만 잘린다. ai-parity.test.ts 가 두 값의 일치를 강제한다.
|
|
1631
1683
|
max_tokens: 2e3,
|
|
1632
|
-
system:
|
|
1684
|
+
system: M4().system,
|
|
1633
1685
|
messages: [{
|
|
1634
1686
|
role: "user",
|
|
1635
|
-
content:
|
|
1687
|
+
content: M4().userPrompt(commitsText, localeList)
|
|
1636
1688
|
}]
|
|
1637
1689
|
});
|
|
1638
1690
|
const text = response.content[0].type === "text" ? response.content[0].text : "";
|
|
1639
1691
|
const match = text.match(/\{[\s\S]*\}/);
|
|
1640
|
-
if (!match) throw new Error(
|
|
1692
|
+
if (!match) throw new Error(M4().parseFailed);
|
|
1641
1693
|
return JSON.parse(match[0]);
|
|
1642
1694
|
}
|
|
1643
1695
|
function generateTemplate(commits, locales) {
|
|
@@ -1647,7 +1699,7 @@ function generateTemplate(commits, locales) {
|
|
|
1647
1699
|
});
|
|
1648
1700
|
const concise = items.slice(0, 3).join("\n");
|
|
1649
1701
|
const detailed = items.join("\n");
|
|
1650
|
-
const marketing =
|
|
1702
|
+
const marketing = M4().marketingTemplate(items.slice(0, 5).join("\n"));
|
|
1651
1703
|
const localized = Object.fromEntries(locales.map((l) => [l, concise]));
|
|
1652
1704
|
return { concise, detailed, marketing, localized };
|
|
1653
1705
|
}
|
|
@@ -1662,43 +1714,43 @@ function parseFirstApp(text) {
|
|
|
1662
1714
|
async function cmdNotes(argv) {
|
|
1663
1715
|
const args = parseArgs(argv);
|
|
1664
1716
|
const cwd = process.cwd();
|
|
1665
|
-
process.stdout.write(kleur3.bold(
|
|
1717
|
+
process.stdout.write(kleur3.bold(M4().title));
|
|
1666
1718
|
if (!isGitRepo(cwd)) {
|
|
1667
|
-
process.stdout.write(kleur3.red(
|
|
1719
|
+
process.stdout.write(kleur3.red(M4().notGitRepo));
|
|
1668
1720
|
process.exit(1);
|
|
1669
1721
|
}
|
|
1670
1722
|
const latestTag = getLatestTag(cwd);
|
|
1671
1723
|
const fromRef = args.from ?? latestTag ?? void 0;
|
|
1672
1724
|
process.stdout.write(
|
|
1673
|
-
kleur3.dim(fromRef ?
|
|
1725
|
+
kleur3.dim(fromRef ? M4().range(fromRef, args.to) : M4().recentCommits(args.limit))
|
|
1674
1726
|
);
|
|
1675
1727
|
const commits = getGitLog(cwd, { from: fromRef, to: args.to, limit: args.limit });
|
|
1676
1728
|
if (commits.length === 0) {
|
|
1677
|
-
process.stdout.write(kleur3.yellow(
|
|
1729
|
+
process.stdout.write(kleur3.yellow(M4().noCommits));
|
|
1678
1730
|
process.exit(0);
|
|
1679
1731
|
}
|
|
1680
|
-
process.stdout.write(kleur3.dim(
|
|
1732
|
+
process.stdout.write(kleur3.dim(M4().analyzing(commits.length)));
|
|
1681
1733
|
let result;
|
|
1682
1734
|
if (process.env.ANTHROPIC_API_KEY) {
|
|
1683
|
-
process.stdout.write(
|
|
1735
|
+
process.stdout.write(M4().generating);
|
|
1684
1736
|
try {
|
|
1685
1737
|
result = await generateWithClaude(formatCommitsForPrompt(commits), args.locales);
|
|
1686
1738
|
} catch (e) {
|
|
1687
|
-
process.stdout.write(kleur3.yellow(
|
|
1739
|
+
process.stdout.write(kleur3.yellow(M4().aiFailed(e.message)));
|
|
1688
1740
|
result = generateTemplate(commits, args.locales);
|
|
1689
1741
|
}
|
|
1690
1742
|
} else {
|
|
1691
|
-
process.stdout.write(kleur3.dim(
|
|
1743
|
+
process.stdout.write(kleur3.dim(M4().noApiKey) + kleur3.dim(M4().noApiKeyHint));
|
|
1692
1744
|
result = generateTemplate(commits, args.locales);
|
|
1693
1745
|
}
|
|
1694
|
-
process.stdout.write(kleur3.bold(
|
|
1746
|
+
process.stdout.write(kleur3.bold(M4().hdrConcise));
|
|
1695
1747
|
process.stdout.write(result.concise + "\n\n");
|
|
1696
|
-
process.stdout.write(kleur3.bold(
|
|
1748
|
+
process.stdout.write(kleur3.bold(M4().hdrDetailed));
|
|
1697
1749
|
process.stdout.write(result.detailed + "\n\n");
|
|
1698
|
-
process.stdout.write(kleur3.bold(
|
|
1750
|
+
process.stdout.write(kleur3.bold(M4().hdrMarketing));
|
|
1699
1751
|
process.stdout.write(result.marketing + "\n\n");
|
|
1700
1752
|
if (Object.keys(result.localized).length > 0) {
|
|
1701
|
-
process.stdout.write(kleur3.bold(
|
|
1753
|
+
process.stdout.write(kleur3.bold(M4().hdrLocalized));
|
|
1702
1754
|
for (const [locale, text] of Object.entries(result.localized)) {
|
|
1703
1755
|
process.stdout.write(kleur3.dim(`[${locale}]
|
|
1704
1756
|
`) + text + "\n\n");
|
|
@@ -1708,15 +1760,15 @@ async function cmdNotes(argv) {
|
|
|
1708
1760
|
if (!args.apply && !shouldPrompt) return;
|
|
1709
1761
|
const cfg = await getEffectiveConfig();
|
|
1710
1762
|
if (!cfg) {
|
|
1711
|
-
process.stdout.write(kleur3.yellow(
|
|
1763
|
+
process.stdout.write(kleur3.yellow(M4().needAccount));
|
|
1712
1764
|
return;
|
|
1713
1765
|
}
|
|
1714
1766
|
let selectedText = result.concise;
|
|
1715
1767
|
let userSelectedTone = false;
|
|
1716
1768
|
if (shouldPrompt) {
|
|
1717
|
-
const choice = await promptUser(
|
|
1769
|
+
const choice = await promptUser(M4().choosePrompt);
|
|
1718
1770
|
if (!choice) {
|
|
1719
|
-
process.stdout.write(kleur3.dim(
|
|
1771
|
+
process.stdout.write(kleur3.dim(M4().skipped));
|
|
1720
1772
|
return;
|
|
1721
1773
|
}
|
|
1722
1774
|
if (choice === "2") selectedText = result.detailed;
|
|
@@ -1725,18 +1777,18 @@ async function cmdNotes(argv) {
|
|
|
1725
1777
|
}
|
|
1726
1778
|
const appsResult = await mcpCall(cfg.endpoint, cfg.token, "list_apps", {});
|
|
1727
1779
|
if (appsResult.isError) {
|
|
1728
|
-
process.stdout.write(kleur3.red(
|
|
1780
|
+
process.stdout.write(kleur3.red(M4().listAppsFailed(appsResult.text)));
|
|
1729
1781
|
return;
|
|
1730
1782
|
}
|
|
1731
1783
|
const app = parseFirstApp(appsResult.text);
|
|
1732
1784
|
if (!app) {
|
|
1733
|
-
process.stdout.write(kleur3.yellow(
|
|
1785
|
+
process.stdout.write(kleur3.yellow(M4().noApps));
|
|
1734
1786
|
return;
|
|
1735
1787
|
}
|
|
1736
1788
|
if (userSelectedTone && args.locales.length > 1) {
|
|
1737
|
-
process.stdout.write(kleur3.dim(
|
|
1789
|
+
process.stdout.write(kleur3.dim(M4().toneToAllLocales));
|
|
1738
1790
|
}
|
|
1739
|
-
process.stdout.write(
|
|
1791
|
+
process.stdout.write(M4().applying);
|
|
1740
1792
|
for (const locale of args.locales) {
|
|
1741
1793
|
const text = userSelectedTone ? selectedText : result.localized[locale] ?? selectedText;
|
|
1742
1794
|
const r = await mcpCall(cfg.endpoint, cfg.token, "apply_release_notes", {
|
|
@@ -1746,7 +1798,7 @@ async function cmdNotes(argv) {
|
|
|
1746
1798
|
text
|
|
1747
1799
|
});
|
|
1748
1800
|
process.stdout.write(
|
|
1749
|
-
r.isError ? kleur3.red(
|
|
1801
|
+
r.isError ? kleur3.red(M4().applyFailed(locale, r.text)) : kleur3.green(M4().applied(locale))
|
|
1750
1802
|
);
|
|
1751
1803
|
}
|
|
1752
1804
|
}
|
|
@@ -1755,7 +1807,7 @@ async function cmdNotes(argv) {
|
|
|
1755
1807
|
import { createInterface as createInterface2 } from "readline/promises";
|
|
1756
1808
|
import Anthropic2 from "@anthropic-ai/sdk";
|
|
1757
1809
|
import kleur4 from "kleur";
|
|
1758
|
-
var
|
|
1810
|
+
var M5 = catalog(
|
|
1759
1811
|
{
|
|
1760
1812
|
toneGuides: {
|
|
1761
1813
|
friendly: "\uCE5C\uADFC\uD558\uACE0 \uB530\uB73B\uD558\uAC8C. \uC774\uBAA8\uC9C0 1~2\uAC1C \uC0AC\uC6A9. \uAC10\uC0AC \uC778\uC0AC\uB85C \uC2DC\uC791.",
|
|
@@ -1901,7 +1953,7 @@ function detectSentiment(text) {
|
|
|
1901
1953
|
}
|
|
1902
1954
|
async function generateReply(opts) {
|
|
1903
1955
|
const client = new Anthropic2({ apiKey: process.env.ANTHROPIC_API_KEY });
|
|
1904
|
-
const m =
|
|
1956
|
+
const m = M5();
|
|
1905
1957
|
const toneGuides = m.toneGuides;
|
|
1906
1958
|
const sentimentPrompts = m.sentimentPrompts;
|
|
1907
1959
|
const localeNames = m.localeNames;
|
|
@@ -1927,71 +1979,71 @@ async function generateReply(opts) {
|
|
|
1927
1979
|
}
|
|
1928
1980
|
async function cmdReview(argv) {
|
|
1929
1981
|
const args = parseArgs2(argv);
|
|
1930
|
-
process.stdout.write(kleur4.bold(
|
|
1982
|
+
process.stdout.write(kleur4.bold(M5().title));
|
|
1931
1983
|
if (!process.env.ANTHROPIC_API_KEY) {
|
|
1932
|
-
process.stdout.write(kleur4.red(
|
|
1933
|
-
process.stdout.write(kleur4.dim(
|
|
1984
|
+
process.stdout.write(kleur4.red(M5().noApiKey));
|
|
1985
|
+
process.stdout.write(kleur4.dim(M5().noApiKeyHint));
|
|
1934
1986
|
process.exit(1);
|
|
1935
1987
|
}
|
|
1936
1988
|
let reviewText = args.text;
|
|
1937
1989
|
if (!reviewText) {
|
|
1938
1990
|
if (args.noInteractive) {
|
|
1939
|
-
process.stdout.write(kleur4.red(
|
|
1991
|
+
process.stdout.write(kleur4.red(M5().textRequired));
|
|
1940
1992
|
process.exit(1);
|
|
1941
1993
|
}
|
|
1942
|
-
process.stdout.write(kleur4.dim(
|
|
1994
|
+
process.stdout.write(kleur4.dim(M5().enterReview));
|
|
1943
1995
|
reviewText = await promptUser2("> ");
|
|
1944
1996
|
if (!reviewText) {
|
|
1945
|
-
process.stdout.write(kleur4.yellow(
|
|
1997
|
+
process.stdout.write(kleur4.yellow(M5().noInput));
|
|
1946
1998
|
process.exit(0);
|
|
1947
1999
|
}
|
|
1948
2000
|
}
|
|
1949
2001
|
if (args.rating !== void 0) {
|
|
1950
2002
|
const stars = "\u2605".repeat(args.rating) + "\u2606".repeat(5 - args.rating);
|
|
1951
|
-
process.stdout.write(kleur4.dim(
|
|
2003
|
+
process.stdout.write(kleur4.dim(M5().meta(stars, args.tone, args.language)));
|
|
1952
2004
|
}
|
|
1953
|
-
process.stdout.write(
|
|
2005
|
+
process.stdout.write(M5().generating);
|
|
1954
2006
|
const reply = await generateReply({ ...args, text: reviewText });
|
|
1955
|
-
process.stdout.write("\n" + kleur4.bold(
|
|
2007
|
+
process.stdout.write("\n" + kleur4.bold(M5().hdrReply));
|
|
1956
2008
|
process.stdout.write(reply + "\n");
|
|
1957
|
-
process.stdout.write(kleur4.dim(
|
|
2009
|
+
process.stdout.write(kleur4.dim(M5().draftWarning));
|
|
1958
2010
|
const shouldPrompt = !args.apply && !args.noInteractive && process.stdout.isTTY;
|
|
1959
2011
|
if (!args.apply && !shouldPrompt) return;
|
|
1960
2012
|
let doApply = args.apply;
|
|
1961
2013
|
if (shouldPrompt) {
|
|
1962
|
-
const ans = await promptUser2(
|
|
2014
|
+
const ans = await promptUser2(M5().postPrompt);
|
|
1963
2015
|
doApply = ans.toLowerCase() === "y";
|
|
1964
2016
|
}
|
|
1965
2017
|
if (!doApply) {
|
|
1966
|
-
process.stdout.write(kleur4.dim(
|
|
2018
|
+
process.stdout.write(kleur4.dim(M5().skipped));
|
|
1967
2019
|
return;
|
|
1968
2020
|
}
|
|
1969
2021
|
const cfg = await getEffectiveConfig();
|
|
1970
2022
|
if (!cfg) {
|
|
1971
|
-
process.stdout.write(kleur4.yellow(
|
|
2023
|
+
process.stdout.write(kleur4.yellow(M5().needAccount));
|
|
1972
2024
|
return;
|
|
1973
2025
|
}
|
|
1974
2026
|
let reviewId = args.reviewId;
|
|
1975
2027
|
let packageName = args.packageName;
|
|
1976
2028
|
if (!reviewId || !packageName) {
|
|
1977
2029
|
if (args.noInteractive) {
|
|
1978
|
-
process.stdout.write(kleur4.red(
|
|
2030
|
+
process.stdout.write(kleur4.red(M5().idsRequired));
|
|
1979
2031
|
process.exit(1);
|
|
1980
2032
|
}
|
|
1981
|
-
if (!packageName) packageName = await promptUser2(
|
|
1982
|
-
if (!reviewId) reviewId = await promptUser2(
|
|
2033
|
+
if (!packageName) packageName = await promptUser2(M5().packagePrompt);
|
|
2034
|
+
if (!reviewId) reviewId = await promptUser2(M5().reviewIdPrompt);
|
|
1983
2035
|
}
|
|
1984
2036
|
if (!reviewId || !packageName) {
|
|
1985
|
-
process.stdout.write(kleur4.yellow(
|
|
2037
|
+
process.stdout.write(kleur4.yellow(M5().notEnoughInfo));
|
|
1986
2038
|
return;
|
|
1987
2039
|
}
|
|
1988
|
-
process.stdout.write(
|
|
2040
|
+
process.stdout.write(M5().posting);
|
|
1989
2041
|
const r = await mcpCall(cfg.endpoint, cfg.token, "playstore_reply_review", {
|
|
1990
2042
|
package_name: packageName,
|
|
1991
2043
|
review_id: reviewId,
|
|
1992
2044
|
reply_text: reply
|
|
1993
2045
|
});
|
|
1994
|
-
process.stdout.write(r.isError ? kleur4.red(
|
|
2046
|
+
process.stdout.write(r.isError ? kleur4.red(M5().postFailed(r.text)) : kleur4.green(M5().posted));
|
|
1995
2047
|
}
|
|
1996
2048
|
|
|
1997
2049
|
// src/auth.ts
|
|
@@ -1999,7 +2051,7 @@ import kleur5 from "kleur";
|
|
|
1999
2051
|
function log(msg) {
|
|
2000
2052
|
process.stdout.write(msg + "\n");
|
|
2001
2053
|
}
|
|
2002
|
-
var
|
|
2054
|
+
var M6 = catalog(
|
|
2003
2055
|
{
|
|
2004
2056
|
help: `${kleur5.bold("mimi-seed auth")} \u2014 \uB85C\uCEEC \uC790\uACA9\uC99D\uBA85 \uC778\uC99D/\uAD00\uB9AC
|
|
2005
2057
|
|
|
@@ -2082,7 +2134,7 @@ ${kleur5.dim(`Under the hood this calls the mimi-seed-*-auth CLIs from ${MCP_PKG
|
|
|
2082
2134
|
}
|
|
2083
2135
|
);
|
|
2084
2136
|
function printAuthHelp() {
|
|
2085
|
-
log(
|
|
2137
|
+
log(M6().help);
|
|
2086
2138
|
}
|
|
2087
2139
|
function printAllCredStatus() {
|
|
2088
2140
|
log(kleur5.bold(t().auth.statusTitle + " ") + kleur5.dim("(~/.mimi-seed)"));
|
|
@@ -2093,7 +2145,7 @@ function printAllCredStatus() {
|
|
|
2093
2145
|
const tail = d.freshness === "expired" ? kleur5.red(`${t().setup.tokenExpired} \u2192 ${spec.fix}`) : d.freshness === "expiring" ? kleur5.yellow(`${t().setup.tokenExpiring(d.daysRemaining ?? 0)} \u2192 ${spec.fix}`) : d.present ? kleur5.dim(d.detail ?? "") : kleur5.dim(`\u2192 ${spec.fix}`);
|
|
2094
2146
|
log(` ${mark} ${credLabel(spec).padEnd(24)} ${tail}`);
|
|
2095
2147
|
}
|
|
2096
|
-
log(kleur5.dim(
|
|
2148
|
+
log(kleur5.dim(M6().connectAll));
|
|
2097
2149
|
}
|
|
2098
2150
|
async function cmdAuth(args) {
|
|
2099
2151
|
const sub = args[0];
|
|
@@ -2117,7 +2169,7 @@ async function cmdAuth(args) {
|
|
|
2117
2169
|
if (sub === "threads") return void exitWith(await runMcpBin("mimi-seed-social-auth", ["threads", ...rest]));
|
|
2118
2170
|
if (sub === "tiktok") return void exitWith(await runMcpBin("mimi-seed-tiktok-business-auth", rest));
|
|
2119
2171
|
if (sub === "ci") {
|
|
2120
|
-
const { cmdSetup: cmdSetup2 } = await import("./setup-
|
|
2172
|
+
const { cmdSetup: cmdSetup2 } = await import("./setup-Z34QP6PO.js");
|
|
2121
2173
|
await cmdSetup2(["--only", "github,gitlab", "--reconnect", "github,gitlab"]);
|
|
2122
2174
|
return;
|
|
2123
2175
|
}
|
|
@@ -2200,7 +2252,7 @@ import kleur7 from "kleur";
|
|
|
2200
2252
|
function log3(msg) {
|
|
2201
2253
|
process.stdout.write(msg + "\n");
|
|
2202
2254
|
}
|
|
2203
|
-
var
|
|
2255
|
+
var M7 = catalog(
|
|
2204
2256
|
{
|
|
2205
2257
|
killedPid: (pid) => ` PID ${pid} \uC885\uB8CC`,
|
|
2206
2258
|
title: (server) => `MCP \uC11C\uBC84 \uC7AC\uC2DC\uC791: ${server}`,
|
|
@@ -2271,7 +2323,7 @@ function detectMcpClient(env = process.env) {
|
|
|
2271
2323
|
return "unknown";
|
|
2272
2324
|
}
|
|
2273
2325
|
function recoveryMessages(client, killed) {
|
|
2274
|
-
const m =
|
|
2326
|
+
const m = M7();
|
|
2275
2327
|
if (client === "codex") {
|
|
2276
2328
|
return { hint: killed ? m.codexKilledHint : m.codexNoProcessHint, verify: m.codexVerify };
|
|
2277
2329
|
}
|
|
@@ -2363,7 +2415,7 @@ function killByMarkers(markers) {
|
|
|
2363
2415
|
for (const pid of pids) {
|
|
2364
2416
|
try {
|
|
2365
2417
|
execSync2(`taskkill /F /PID ${pid}`, { stdio: "pipe" });
|
|
2366
|
-
log3(kleur7.dim(
|
|
2418
|
+
log3(kleur7.dim(M7().killedPid(pid)));
|
|
2367
2419
|
killed++;
|
|
2368
2420
|
} catch {
|
|
2369
2421
|
}
|
|
@@ -2374,7 +2426,7 @@ function killByMarkers(markers) {
|
|
|
2374
2426
|
for (const pid of findPids(markers)) {
|
|
2375
2427
|
try {
|
|
2376
2428
|
process.kill(pid, "SIGTERM");
|
|
2377
|
-
log3(kleur7.dim(
|
|
2429
|
+
log3(kleur7.dim(M7().killedPid(String(pid))));
|
|
2378
2430
|
killed += 1;
|
|
2379
2431
|
} catch {
|
|
2380
2432
|
}
|
|
@@ -2384,40 +2436,40 @@ function killByMarkers(markers) {
|
|
|
2384
2436
|
}
|
|
2385
2437
|
async function cmdRestart(args) {
|
|
2386
2438
|
const serverName = args[0] ?? "mimi-seed";
|
|
2387
|
-
log3(kleur7.bold(
|
|
2439
|
+
log3(kleur7.bold(M7().title(serverName)));
|
|
2388
2440
|
log3("");
|
|
2389
2441
|
const { servers, sources } = collectServers();
|
|
2390
2442
|
const cfg = resolveServerConfig(servers, serverName);
|
|
2391
2443
|
if (!cfg) {
|
|
2392
2444
|
const names = Object.keys(servers);
|
|
2393
|
-
const available = names.length ? names.join(", ") :
|
|
2394
|
-
log3(kleur7.red(
|
|
2395
|
-
log3(kleur7.dim(
|
|
2396
|
-
log3(kleur7.dim(
|
|
2445
|
+
const available = names.length ? names.join(", ") : M7().none;
|
|
2446
|
+
log3(kleur7.red(M7().notFound(serverName)));
|
|
2447
|
+
log3(kleur7.dim(M7().searched(sources.length ? sources.join(", ") : M7().noConfig)));
|
|
2448
|
+
log3(kleur7.dim(M7().registered(available)));
|
|
2397
2449
|
process.exit(1);
|
|
2398
2450
|
}
|
|
2399
2451
|
if (cfg.type === "http" || cfg.type === "sse") {
|
|
2400
|
-
log3(kleur7.yellow(
|
|
2401
|
-
log3(kleur7.dim(
|
|
2452
|
+
log3(kleur7.yellow(M7().httpServer(serverName)));
|
|
2453
|
+
log3(kleur7.dim(M7().httpHint));
|
|
2402
2454
|
return;
|
|
2403
2455
|
}
|
|
2404
2456
|
const markers = candidateMarkers(cfg);
|
|
2405
2457
|
const marker = markers[0] ?? null;
|
|
2406
2458
|
if (!marker) {
|
|
2407
|
-
log3(kleur7.yellow(
|
|
2408
|
-
log3(kleur7.dim(
|
|
2459
|
+
log3(kleur7.yellow(M7().noMarker));
|
|
2460
|
+
log3(kleur7.dim(M7().configLine(JSON.stringify(cfg))));
|
|
2409
2461
|
process.exit(1);
|
|
2410
2462
|
}
|
|
2411
|
-
log3(kleur7.dim(
|
|
2463
|
+
log3(kleur7.dim(M7().markerLine(marker)));
|
|
2412
2464
|
const { killed } = killByMarkers(markers);
|
|
2413
2465
|
const recovery = recoveryMessages(detectMcpClient(), killed > 0);
|
|
2414
2466
|
if (killed === 0) {
|
|
2415
|
-
log3(kleur7.yellow(
|
|
2467
|
+
log3(kleur7.yellow(M7().noProcess));
|
|
2416
2468
|
log3(kleur7.dim(recovery.hint));
|
|
2417
|
-
log3(kleur7.yellow(
|
|
2469
|
+
log3(kleur7.yellow(M7().unknownWriteOutcome));
|
|
2418
2470
|
} else {
|
|
2419
2471
|
log3("");
|
|
2420
|
-
log3(kleur7.green(
|
|
2472
|
+
log3(kleur7.green(M7().killed(serverName, killed)));
|
|
2421
2473
|
log3(kleur7.dim(recovery.hint));
|
|
2422
2474
|
}
|
|
2423
2475
|
log3("");
|
|
@@ -2432,7 +2484,7 @@ import kleur8 from "kleur";
|
|
|
2432
2484
|
var SERVER_NAME = "mimi-seed";
|
|
2433
2485
|
var CODEX_REMOTE_NAME = "mimi-seed-remote";
|
|
2434
2486
|
var CODEX_TOKEN_ENV = "MIMI_SEED_TOKEN";
|
|
2435
|
-
var
|
|
2487
|
+
var M8 = catalog(
|
|
2436
2488
|
{
|
|
2437
2489
|
claudeTitle: "Claude Code MCP \uB4F1\uB85D \u2014 \uC544\uB798 \uD55C \uC904\uC744 \uADF8\uB300\uB85C \uC2E4\uD589\uD558\uC138\uC694:",
|
|
2438
2490
|
tokenWarning: (loc) => ` \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 ${loc} \uC5D0\uB3C4 \uC800\uC7A5\uB418\uC5B4 \uC788\uC2B5\uB2C8\uB2E4.`,
|
|
@@ -2478,14 +2530,14 @@ function claudeMcpAddCommand(cfg) {
|
|
|
2478
2530
|
function printMcpSetup(cfg) {
|
|
2479
2531
|
process.stdout.write(
|
|
2480
2532
|
[
|
|
2481
|
-
kleur8.bold(
|
|
2533
|
+
kleur8.bold(M8().claudeTitle),
|
|
2482
2534
|
kleur8.cyan(` ${claudeMcpAddCommand(cfg)}`),
|
|
2483
|
-
kleur8.dim(
|
|
2535
|
+
kleur8.dim(M8().tokenWarning(CONFIG_LOCATION_HINT)),
|
|
2484
2536
|
"",
|
|
2485
|
-
kleur8.dim(
|
|
2537
|
+
kleur8.dim(M8().codexTitle),
|
|
2486
2538
|
kleur8.dim(" mimi-seed mcp codex --write"),
|
|
2487
|
-
kleur8.dim(
|
|
2488
|
-
kleur8.dim(
|
|
2539
|
+
kleur8.dim(M8().codexEnvNote),
|
|
2540
|
+
kleur8.dim(M8().codexManual)
|
|
2489
2541
|
].join("\n") + "\n"
|
|
2490
2542
|
);
|
|
2491
2543
|
}
|
|
@@ -2563,7 +2615,7 @@ async function ensureReleaseManifest(cwd) {
|
|
|
2563
2615
|
// src/index.ts
|
|
2564
2616
|
var DEFAULT_WEB_BASE = process.env.MIMI_SEED_WEB_BASE ?? "https://mimi-seed.pryzm.gg";
|
|
2565
2617
|
var DEFAULT_MCP_ENDPOINT = `${DEFAULT_WEB_BASE}/api/mcp`;
|
|
2566
|
-
var
|
|
2618
|
+
var M9 = catalog(
|
|
2567
2619
|
{
|
|
2568
2620
|
noProjectSignal: "\u26A0 package.json / app.json / android / ios \uB97C \uCC3E\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4. \uADF8\uB798\uB3C4 \uC9C4\uD589\uD569\uB2C8\uB2E4.",
|
|
2569
2621
|
detecting: "\u{1F50D} \uC571 \uAC10\uC9C0 \uC911...",
|
|
@@ -2614,6 +2666,7 @@ var M8 = catalog(
|
|
|
2614
2666
|
claudeWarn: " \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.",
|
|
2615
2667
|
// 명령별 상세 사용법 (SSOT). `mimi-seed <command> --help` 와 overview 가 공유.
|
|
2616
2668
|
usage: {
|
|
2669
|
+
telemetry: "mimi-seed telemetry on|off|status \u2014 \uC120\uD0DD\uC801 \uC0AC\uC6A9\uB7C9 \uCE21\uC815. \uAE30\uBCF8 \uAEBC\uC9D0. \uC784\uC758 \uC124\uCE58 ID, \uD504\uB85C\uC81D\uD2B8 \uD574\uC2DC, \uBC84\uC804, OS, \uACB0\uACFC \uCF54\uB4DC\uC640 \uC2E4\uD589\uC2DC\uAC04\uC744 \uC804\uC1A1\uD569\uB2C8\uB2E4. \uAC1C\uC778\uC815\uBCF4 \uC548\uB0B4: https://mimi-seed.pryzm.gg/privacy/sdk-usage . MIMI_SEED_TELEMETRY=0\uC740 \uD56D\uC0C1 \uC804\uC1A1\uC744 \uB055\uB2C8\uB2E4.",
|
|
2617
2670
|
init: `${kleur9.bold("mimi-seed init")} \u2014 \uD604\uC7AC \uD504\uB85C\uC81D\uD2B8\uB97C Mimi Seed\uC5D0 \uC5F0\uACB0
|
|
2618
2671
|
|
|
2619
2672
|
\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
|
|
@@ -2683,17 +2736,17 @@ ${kleur9.dim("setup \uB9C8\uBC95\uC0AC\uAC00 \uCCAB \uC2E4\uD589 \uB54C \uBB3C\u
|
|
|
2683
2736
|
|
|
2684
2737
|
\uC635\uC158:
|
|
2685
2738
|
--platform android|ios \uBC30\uD3EC \uD50C\uB7AB\uD3FC (\uAE30\uBCF8: android)
|
|
2686
|
-
--app <id> \uC571 ID \
|
|
2687
|
-
--version-code <n> \uBE4C\uB4DC \uBC88\uD638 \
|
|
2739
|
+
--app <id> \uBC30\uD3EC\uD560 \uC6D0\uACA9 \uC571 ID (\uC2E4\uC81C \uC2E4\uD589 \uD544\uC218)
|
|
2740
|
+
--version-code <n> \uC2E4\uC81C \uC2A4\uD1A0\uC5B4 \uBE4C\uB4DC \uBC88\uD638 (CI \uC2E4\uD589 \uBC88\uD638 \uC544\uB2D8)
|
|
2688
2741
|
--from <ref> \uCEE4\uBC0B \uBC94\uC704 \uC2DC\uC791 (\uB9B4\uB9AC\uC988 \uB178\uD2B8\uC6A9)
|
|
2689
2742
|
--to <ref> \uCEE4\uBC0B \uBC94\uC704 \uB05D (\uAE30\uBCF8: HEAD)
|
|
2690
2743
|
--language <\uCF54\uB4DC> \uB9B4\uB9AC\uC988 \uB178\uD2B8 \uC5B8\uC5B4 (\uAE30\uBCF8: ko-KR)
|
|
2691
|
-
--dry-run \
|
|
2692
|
-
--yes, -y \
|
|
2744
|
+
--dry-run \uB85C\uCEEC \uACC4\uD68D\uB9CC \uCD9C\uB825 (\uB124\uD2B8\uC6CC\uD06C\xB7\uBE4C\uB4DC\xB7\uC4F0\uAE30 \uC5C6\uC74C)
|
|
2745
|
+
--yes, -y CI \uC2E4\uD589\xB7\uC2A4\uD1A0\uC5B4 \uBC30\uD3EC \uBA85\uC2DC\uC801 \uC2B9\uC778 (\uC2E4\uD589 \uD544\uC218)
|
|
2693
2746
|
--skip-build CI \uBE4C\uB4DC \uAC74\uB108\uB700 (--version-code \uD544\uC218)
|
|
2694
2747
|
--ci jenkins|github|gitlab CI \uAC15\uC81C \uC120\uD0DD (\uAE30\uBCF8: auto)
|
|
2695
2748
|
--workflow <file> GitHub workflow \uD30C\uC77C (\uC608: deploy.yml)
|
|
2696
|
-
--ref <branch|tag>
|
|
2749
|
+
--ref <branch|tag> CI \uC18C\uC2A4 (\uAE30\uBCF8: main, Jenkins\uB294 \uBE0C\uB79C\uCE58\uB9CC)
|
|
2697
2750
|
setup-jenkins / setup-github / setup-gitlab CI \uC124\uC815 \uB300\uD654\uD615 \uB4F1\uB85D`,
|
|
2698
2751
|
mcp: `${kleur9.bold("mimi-seed mcp")} \u2014 Claude/Codex MCP \uC5F0\uACB0
|
|
2699
2752
|
|
|
@@ -2716,6 +2769,7 @@ ${kleur9.bold("\uBA85\uB839\uC5B4:")}
|
|
|
2716
2769
|
${kleur9.cyan("mimi-seed ga4")} GA4 property\xB7data stream \uC0DD\uC131\xB7\uC870\uD68C
|
|
2717
2770
|
${kleur9.cyan("mimi-seed doctor")} \uD658\uACBD \uC9C4\uB2E8 (\uD1A0\uD070\xB7Git\xB7\uD504\uB85C\uC81D\uD2B8\xB7CI \uCCB4\uD06C)
|
|
2718
2771
|
${kleur9.cyan("mimi-seed check")} \uCD9C\uC2DC \uC804 Readiness \uC810\uAC80
|
|
2772
|
+
${kleur9.cyan("mimi-seed telemetry")} \uC120\uD0DD\uC801 \uC0AC\uC6A9\uB7C9 \uCE21\uC815 \uC124\uC815
|
|
2719
2773
|
${kleur9.cyan("mimi-seed notes")} \uB9B4\uB9AC\uC988 \uB178\uD2B8 \uC0DD\uC131 (git log \u2192 AI \u2192 \uB9C8\uCF13 \uC801\uC6A9)
|
|
2720
2774
|
${kleur9.cyan("mimi-seed review")} \uB9AC\uBDF0 \uB2F5\uBCC0 AI \uCD08\uC548 \uC0DD\uC131 \uBC0F Play Store \uAC8C\uC2DC
|
|
2721
2775
|
${kleur9.cyan("mimi-seed deploy")} \uC571 \uC790\uB3D9 \uBC30\uD3EC (CI \u2192 Play Store/App Store)
|
|
@@ -2783,6 +2837,7 @@ ${kleur9.bold("\uD658\uACBD\uBCC0\uC218:")}
|
|
|
2783
2837
|
claudeTitle: "Claude Code MCP registration \u2014 run this one line as-is:",
|
|
2784
2838
|
claudeWarn: " \u26A0 This command contains the real token (it stays in your shell history). The token is also stored in ~/.mimi-seed/config.json.",
|
|
2785
2839
|
usage: {
|
|
2840
|
+
telemetry: "mimi-seed telemetry on|off|status \u2014 optional usage measurement, off by default. Sends a random installation ID, project hash, version, OS, result codes and duration. Privacy: https://mimi-seed.pryzm.gg/privacy/sdk-usage . MIMI_SEED_TELEMETRY=0 always disables transmission.",
|
|
2786
2841
|
init: `${kleur9.bold("mimi-seed init")} \u2014 connect the current project to Mimi Seed
|
|
2787
2842
|
|
|
2788
2843
|
Auto-detects apps (Expo/Gradle/Info.plist/pbxproj) \u2192 issues a PAT in the browser (remote MCP) \u2192 registers the apps
|
|
@@ -2852,17 +2907,17 @@ Options:
|
|
|
2852
2907
|
|
|
2853
2908
|
Options:
|
|
2854
2909
|
--platform android|ios target platform (default: android)
|
|
2855
|
-
--app <id> app ID
|
|
2856
|
-
--version-code <n>
|
|
2910
|
+
--app <id> remote app ID (required for execution)
|
|
2911
|
+
--version-code <n> actual store build number (not a CI run ID)
|
|
2857
2912
|
--from <ref> commit range start (for release notes)
|
|
2858
2913
|
--to <ref> commit range end (default: HEAD)
|
|
2859
2914
|
--language <code> release notes language (default: ko-KR)
|
|
2860
|
-
--dry-run
|
|
2861
|
-
--yes, -y
|
|
2915
|
+
--dry-run print a local plan (no network, builds or writes)
|
|
2916
|
+
--yes, -y explicitly approve CI and store release (required)
|
|
2862
2917
|
--skip-build skip the CI build (--version-code required)
|
|
2863
2918
|
--ci jenkins|github|gitlab force the CI provider (default: auto)
|
|
2864
2919
|
--workflow <file> GitHub workflow file (e.g. deploy.yml)
|
|
2865
|
-
--ref <branch|tag>
|
|
2920
|
+
--ref <branch|tag> CI source (default: main; Jenkins: branches only)
|
|
2866
2921
|
setup-jenkins / setup-github / setup-gitlab interactive CI setup`,
|
|
2867
2922
|
mcp: `${kleur9.bold("mimi-seed mcp")} \u2014 Claude/Codex MCP connection
|
|
2868
2923
|
|
|
@@ -2885,6 +2940,7 @@ ${kleur9.bold("Commands:")}
|
|
|
2885
2940
|
${kleur9.cyan("mimi-seed ga4")} create and list GA4 properties and data streams
|
|
2886
2941
|
${kleur9.cyan("mimi-seed doctor")} environment check (token \xB7 Git \xB7 project \xB7 CI)
|
|
2887
2942
|
${kleur9.cyan("mimi-seed check")} pre-release readiness check
|
|
2943
|
+
${kleur9.cyan("mimi-seed telemetry")} optional usage measurement settings
|
|
2888
2944
|
${kleur9.cyan("mimi-seed notes")} generate release notes (git log \u2192 AI \u2192 push to stores)
|
|
2889
2945
|
${kleur9.cyan("mimi-seed review")} draft a review reply with AI and post it to the Play Store
|
|
2890
2946
|
${kleur9.cyan("mimi-seed deploy")} automated app release (CI \u2192 Play Store/App Store)
|
|
@@ -2914,37 +2970,37 @@ async function cmdInit(args) {
|
|
|
2914
2970
|
log4(kleur9.dim(cwd));
|
|
2915
2971
|
log4("");
|
|
2916
2972
|
if (!await hasAnyProjectSignal(cwd)) {
|
|
2917
|
-
log4(kleur9.yellow(
|
|
2973
|
+
log4(kleur9.yellow(M9().noProjectSignal));
|
|
2918
2974
|
}
|
|
2919
|
-
log4(
|
|
2975
|
+
log4(M9().detecting);
|
|
2920
2976
|
const hints = await detectHints(cwd);
|
|
2921
2977
|
if (hints.length === 0) {
|
|
2922
|
-
log4(kleur9.yellow(
|
|
2978
|
+
log4(kleur9.yellow(M9().noAppDetected));
|
|
2923
2979
|
} else {
|
|
2924
2980
|
for (const h of hints) {
|
|
2925
2981
|
const tag = [h.packageName && `android:${h.packageName}`, h.bundleId && `ios:${h.bundleId}`].filter(Boolean).join(" ");
|
|
2926
|
-
log4(` \u2022 ${h.name ??
|
|
2982
|
+
log4(` \u2022 ${h.name ?? M9().unnamed} ${kleur9.dim(tag)}`);
|
|
2927
2983
|
}
|
|
2928
2984
|
}
|
|
2929
2985
|
log4("");
|
|
2930
2986
|
if (process.env.MIMI_SEED_TOKEN) {
|
|
2931
2987
|
const cfg2 = await getEffectiveConfig();
|
|
2932
2988
|
if (cfg2 && hints.length > 0) {
|
|
2933
|
-
log4(kleur9.dim(
|
|
2989
|
+
log4(kleur9.dim(M9().ciMode));
|
|
2934
2990
|
const payload = hints.map((h) => ({ name: h.name, packageName: h.packageName, bundleId: h.bundleId }));
|
|
2935
2991
|
const result = await mcpCall(cfg2.endpoint, cfg2.token, "sync_apps", { hints: payload });
|
|
2936
2992
|
if (result.isError) {
|
|
2937
|
-
log4(kleur9.red(
|
|
2993
|
+
log4(kleur9.red(M9().syncFailed(result.text)));
|
|
2938
2994
|
} else {
|
|
2939
2995
|
for (const line of result.text.split("\n")) log4(" " + line);
|
|
2940
2996
|
}
|
|
2941
2997
|
}
|
|
2942
2998
|
const manifest2 = await ensureReleaseManifest(cwd);
|
|
2943
|
-
log4(kleur9.dim(
|
|
2944
|
-
log4(kleur9.bold(
|
|
2999
|
+
log4(kleur9.dim(M9().manifest(manifest2.created)));
|
|
3000
|
+
log4(kleur9.bold(M9().doneCi));
|
|
2945
3001
|
return;
|
|
2946
3002
|
}
|
|
2947
|
-
log4(
|
|
3003
|
+
log4(M9().waitingLogin);
|
|
2948
3004
|
const hostName = os3.hostname().slice(0, 32);
|
|
2949
3005
|
const name = `cli-${hostName}`;
|
|
2950
3006
|
const { port, promise } = await awaitHandshake(5 * 60 * 1e3);
|
|
@@ -2956,10 +3012,10 @@ async function cmdInit(args) {
|
|
|
2956
3012
|
try {
|
|
2957
3013
|
handshake = await promise;
|
|
2958
3014
|
} catch (e) {
|
|
2959
|
-
log4(kleur9.red(
|
|
3015
|
+
log4(kleur9.red(M9().connectFailed(e.message)));
|
|
2960
3016
|
process.exit(1);
|
|
2961
3017
|
}
|
|
2962
|
-
log4(kleur9.green(
|
|
3018
|
+
log4(kleur9.green(M9().tokenReceived));
|
|
2963
3019
|
const cfg = {
|
|
2964
3020
|
token: handshake.token,
|
|
2965
3021
|
prefix: handshake.prefix,
|
|
@@ -2968,14 +3024,14 @@ async function cmdInit(args) {
|
|
|
2968
3024
|
createdAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
2969
3025
|
};
|
|
2970
3026
|
await writeConfig(cfg);
|
|
2971
|
-
log4(kleur9.dim(
|
|
3027
|
+
log4(kleur9.dim(M9().saved(CONFIG_LOCATION)));
|
|
2972
3028
|
log4("");
|
|
2973
3029
|
if (hints.length > 0) {
|
|
2974
|
-
log4(
|
|
3030
|
+
log4(M9().registering);
|
|
2975
3031
|
const payload = hints.map((h) => ({ name: h.name, packageName: h.packageName, bundleId: h.bundleId }));
|
|
2976
3032
|
const result = await mcpCall(cfg.endpoint, cfg.token, "sync_apps", { hints: payload });
|
|
2977
3033
|
if (result.isError) {
|
|
2978
|
-
log4(kleur9.red(
|
|
3034
|
+
log4(kleur9.red(M9().syncFailed(result.text)));
|
|
2979
3035
|
} else {
|
|
2980
3036
|
for (const line of result.text.split("\n")) log4(" " + line);
|
|
2981
3037
|
}
|
|
@@ -3029,94 +3085,94 @@ async function cmdInit(args) {
|
|
|
3029
3085
|
if (!fs6.existsSync(claudeAgentPath)) {
|
|
3030
3086
|
fs6.mkdirSync(claudeDir, { recursive: true });
|
|
3031
3087
|
fs6.writeFileSync(claudeAgentPath, agentMd, { mode: 420 });
|
|
3032
|
-
log4(kleur9.dim(
|
|
3088
|
+
log4(kleur9.dim(M9().claudeAgent));
|
|
3033
3089
|
}
|
|
3034
3090
|
const codexAgentPath = path6.join(cwd, "AGENTS.md");
|
|
3035
3091
|
if (!fs6.existsSync(codexAgentPath)) {
|
|
3036
3092
|
fs6.writeFileSync(codexAgentPath, agentMd, { mode: 420 });
|
|
3037
|
-
log4(kleur9.dim(
|
|
3093
|
+
log4(kleur9.dim(M9().codexAgent));
|
|
3038
3094
|
}
|
|
3039
3095
|
const manifest = await ensureReleaseManifest(cwd);
|
|
3040
|
-
log4(kleur9.dim(
|
|
3041
|
-
log4(kleur9.bold(
|
|
3096
|
+
log4(kleur9.dim(M9().manifest(manifest.created)));
|
|
3097
|
+
log4(kleur9.bold(M9().ready));
|
|
3042
3098
|
log4("");
|
|
3043
|
-
log4(
|
|
3044
|
-
log4(kleur9.cyan(
|
|
3045
|
-
log4(kleur9.cyan(
|
|
3046
|
-
log4(kleur9.cyan(
|
|
3099
|
+
log4(M9().askLike);
|
|
3100
|
+
log4(kleur9.cyan(M9().ask1));
|
|
3101
|
+
log4(kleur9.cyan(M9().ask2));
|
|
3102
|
+
log4(kleur9.cyan(M9().ask3));
|
|
3047
3103
|
log4("");
|
|
3048
|
-
log4(
|
|
3104
|
+
log4(M9().dashboard(kleur9.underline(DEFAULT_WEB_BASE + "/apps")));
|
|
3049
3105
|
log4("");
|
|
3050
3106
|
printMcpSetup(cfg);
|
|
3051
3107
|
if (!local) {
|
|
3052
3108
|
log4("");
|
|
3053
|
-
log4(kleur9.bold(
|
|
3054
|
-
log4(kleur9.cyan(
|
|
3055
|
-
log4(kleur9.cyan(
|
|
3109
|
+
log4(kleur9.bold(M9().nextTitle));
|
|
3110
|
+
log4(kleur9.cyan(M9().nextSetup));
|
|
3111
|
+
log4(kleur9.cyan(M9().nextDoctor));
|
|
3056
3112
|
}
|
|
3057
3113
|
if (local) {
|
|
3058
3114
|
log4("");
|
|
3059
|
-
log4(kleur9.bold(
|
|
3060
|
-
log4(kleur9.dim(
|
|
3115
|
+
log4(kleur9.bold(M9().localTitle));
|
|
3116
|
+
log4(kleur9.dim(M9().localIntro));
|
|
3061
3117
|
log4("");
|
|
3062
|
-
log4(
|
|
3118
|
+
log4(M9().localStep1);
|
|
3063
3119
|
await cmdAuth(["login"]);
|
|
3064
3120
|
log4("");
|
|
3065
|
-
log4(
|
|
3121
|
+
log4(M9().localStep2);
|
|
3066
3122
|
log4(kleur9.cyan(" claude mcp add mimi-seed-local -- npx -y @yoonion/mimi-seed-mcp@latest"));
|
|
3067
|
-
log4(kleur9.dim(
|
|
3123
|
+
log4(kleur9.dim(M9().localCodexHint));
|
|
3068
3124
|
log4("");
|
|
3069
|
-
log4(
|
|
3125
|
+
log4(M9().localStep3);
|
|
3070
3126
|
log4(kleur9.cyan(" mimi-seed setup"));
|
|
3071
|
-
log4(kleur9.dim(
|
|
3127
|
+
log4(kleur9.dim(M9().localSetupHint));
|
|
3072
3128
|
}
|
|
3073
3129
|
}
|
|
3074
3130
|
async function cmdStatus() {
|
|
3075
3131
|
const cfg = await getEffectiveConfig();
|
|
3076
3132
|
if (!cfg) {
|
|
3077
|
-
log4(kleur9.yellow(
|
|
3133
|
+
log4(kleur9.yellow(M9().notConnected));
|
|
3078
3134
|
process.exit(1);
|
|
3079
3135
|
}
|
|
3080
|
-
log4(kleur9.bold(
|
|
3081
|
-
log4(
|
|
3082
|
-
log4(
|
|
3136
|
+
log4(kleur9.bold(M9().statusTitle));
|
|
3137
|
+
log4(M9().statusToken(cfg.prefix, cfg.createdAt.slice(0, 10)));
|
|
3138
|
+
log4(M9().statusEndpoint(cfg.endpoint));
|
|
3083
3139
|
log4("");
|
|
3084
|
-
log4(
|
|
3140
|
+
log4(M9().appList);
|
|
3085
3141
|
const r = await mcpCall(cfg.endpoint, cfg.token, "list_apps", {});
|
|
3086
3142
|
if (r.isError) {
|
|
3087
|
-
log4(kleur9.red(
|
|
3143
|
+
log4(kleur9.red(M9().listFailed(r.text)));
|
|
3088
3144
|
process.exit(1);
|
|
3089
3145
|
}
|
|
3090
3146
|
for (const line of r.text.split("\n")) log4(" " + line);
|
|
3091
3147
|
}
|
|
3092
3148
|
async function cmdLogout() {
|
|
3093
3149
|
await deleteConfig();
|
|
3094
|
-
log4(kleur9.green(
|
|
3095
|
-
log4(kleur9.dim(
|
|
3150
|
+
log4(kleur9.green(M9().logoutDone));
|
|
3151
|
+
log4(kleur9.dim(M9().logoutRevoke));
|
|
3096
3152
|
}
|
|
3097
3153
|
async function cmdMcp(args) {
|
|
3098
3154
|
const target = args[0] ?? "help";
|
|
3099
3155
|
const cfg = await getEffectiveConfig();
|
|
3100
3156
|
if (!cfg) {
|
|
3101
|
-
log4(kleur9.yellow(
|
|
3157
|
+
log4(kleur9.yellow(M9().notConnected));
|
|
3102
3158
|
process.exit(1);
|
|
3103
3159
|
}
|
|
3104
3160
|
if (target === "codex") {
|
|
3105
3161
|
if (args.includes("--write")) {
|
|
3106
3162
|
const configPath = await writeCodexMcpConfig(cfg);
|
|
3107
|
-
log4(kleur9.green(
|
|
3163
|
+
log4(kleur9.green(M9().codexWritten));
|
|
3108
3164
|
log4(kleur9.dim(` ${configPath}`));
|
|
3109
|
-
log4(kleur9.dim(
|
|
3165
|
+
log4(kleur9.dim(M9().codexWriteWarn));
|
|
3110
3166
|
log4("");
|
|
3111
|
-
log4(
|
|
3167
|
+
log4(M9().codexVerify);
|
|
3112
3168
|
return;
|
|
3113
3169
|
}
|
|
3114
|
-
log4(kleur9.bold(
|
|
3170
|
+
log4(kleur9.bold(M9().codexTitle));
|
|
3115
3171
|
log4("");
|
|
3116
|
-
log4(
|
|
3172
|
+
log4(M9().codexAuto);
|
|
3117
3173
|
log4(kleur9.cyan(" mimi-seed mcp codex --write"));
|
|
3118
3174
|
log4("");
|
|
3119
|
-
log4(
|
|
3175
|
+
log4(M9().codexManual);
|
|
3120
3176
|
log4(`[mcp_servers.mimi-seed-remote]
|
|
3121
3177
|
url = "${cfg.endpoint}"
|
|
3122
3178
|
bearer_token_env_var = "MIMI_SEED_TOKEN"
|
|
@@ -3124,21 +3180,21 @@ enabled = true`);
|
|
|
3124
3180
|
return;
|
|
3125
3181
|
}
|
|
3126
3182
|
if (target === "claude") {
|
|
3127
|
-
log4(kleur9.bold(
|
|
3183
|
+
log4(kleur9.bold(M9().claudeTitle));
|
|
3128
3184
|
log4(kleur9.cyan(` ${claudeMcpAddCommand(cfg)}`));
|
|
3129
|
-
log4(kleur9.dim(
|
|
3185
|
+
log4(kleur9.dim(M9().claudeWarn));
|
|
3130
3186
|
return;
|
|
3131
3187
|
}
|
|
3132
3188
|
printMcpSetup(cfg);
|
|
3133
3189
|
}
|
|
3134
3190
|
function printCommandHelp(cmd) {
|
|
3135
|
-
const usage =
|
|
3191
|
+
const usage = M9().usage[cmd];
|
|
3136
3192
|
if (!usage) return false;
|
|
3137
3193
|
log4(usage);
|
|
3138
3194
|
return true;
|
|
3139
3195
|
}
|
|
3140
3196
|
function printHelp() {
|
|
3141
|
-
log4(
|
|
3197
|
+
log4(M9().help);
|
|
3142
3198
|
}
|
|
3143
3199
|
async function main() {
|
|
3144
3200
|
const cmd = process.argv[2];
|
|
@@ -3166,6 +3222,9 @@ async function main() {
|
|
|
3166
3222
|
case "check":
|
|
3167
3223
|
await cmdCheck(restArgs);
|
|
3168
3224
|
break;
|
|
3225
|
+
case "telemetry":
|
|
3226
|
+
cmdTelemetry(restArgs);
|
|
3227
|
+
break;
|
|
3169
3228
|
case "notes":
|
|
3170
3229
|
await cmdNotes(restArgs);
|
|
3171
3230
|
break;
|