mimi-seed 0.9.4 → 0.10.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/README.md +6 -1
- package/dist/{chunk-QU2IDWJ2.js → chunk-HCCOWX3G.js} +1 -1
- package/dist/{chunk-BXN3EMF6.js → chunk-PL7N2FSO.js} +62 -13
- package/dist/{chunk-SZQFVTEW.js → chunk-VZQHUWXR.js} +4 -0
- package/dist/index.js +12 -6
- package/dist/{mcp-client-PVWDCYJN.js → mcp-client-DQBKWHT4.js} +2 -2
- package/dist/{setup-3XTSGFEF.js → setup-EQVJO6F7.js} +2 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -19,7 +19,7 @@ npx mimi-seed init
|
|
|
19
19
|
| `mimi-seed init` | 프로젝트를 Mimi Seed에 연결 (PAT 발급 + 앱 자동 등록 + `.claude/mimi-seed.md` / `AGENTS.md` 주입) |
|
|
20
20
|
| `mimi-seed setup` | **가진 계정을 한 번에 연결** (안내형 마법사) — 뭐가 빠졌는지 보여주고, 각 토큰을 어디서 발급받는지 알려줌 |
|
|
21
21
|
| `mimi-seed status` | 연결 상태 + 등록 앱 목록 |
|
|
22
|
-
| `mimi-seed auth` | 자격증명 개별 인증 — `login` / `appstore` / `playstore` / `bigquery` / `jenkins` / `ci` / `googleads` / `facebook` / `instagram` |
|
|
22
|
+
| `mimi-seed auth` | 자격증명 개별 인증 — `login` / `appstore` / `playstore` / `bigquery` / `jenkins` / `ci` / `googleads` / `facebook` / `instagram` / `threads` |
|
|
23
23
|
| `mimi-seed doctor` | 환경 진단 (토큰·Git·앱·CI 한 번에 체크) |
|
|
24
24
|
| `mimi-seed check` | 출시 전 Readiness 점검 (점수 + 블로커) |
|
|
25
25
|
| `mimi-seed notes` | AI 릴리즈 노트 생성 (git log → 3 톤 → 다국어 → 적용) |
|
|
@@ -187,10 +187,15 @@ mimi-seed auth bigquery # BigQuery 서비스 계정 (선택)
|
|
|
187
187
|
mimi-seed auth jenkins # Jenkins (저장 전 서버 프로브)
|
|
188
188
|
mimi-seed auth ci # GitHub Actions / GitLab CI
|
|
189
189
|
mimi-seed auth googleads # Google Ads
|
|
190
|
+
mimi-seed auth meta # Facebook · Instagram · Threads 통합 진입
|
|
190
191
|
mimi-seed auth facebook # Facebook 페이지
|
|
191
192
|
mimi-seed auth instagram # Instagram
|
|
193
|
+
mimi-seed auth threads # Threads
|
|
192
194
|
```
|
|
193
195
|
|
|
196
|
+
Facebook·Instagram·Threads 토큰은 저장된 만료일을 함께 확인합니다. 만료됐거나 7일 이내 만료 예정이면
|
|
197
|
+
`mimi-seed setup`이 자동으로 재연결 목록에 올리며, 위 개별 명령으로 바로 갱신할 수도 있습니다.
|
|
198
|
+
|
|
194
199
|
### login 옵션
|
|
195
200
|
|
|
196
201
|
| 옵션 | 설명 |
|
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
resolveLang,
|
|
6
6
|
t,
|
|
7
7
|
writeSettings
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-VZQHUWXR.js";
|
|
9
9
|
|
|
10
10
|
// src/setup.ts
|
|
11
11
|
import kleur2 from "kleur";
|
|
@@ -45,6 +45,27 @@ function readJson(home, name) {
|
|
|
45
45
|
return null;
|
|
46
46
|
}
|
|
47
47
|
}
|
|
48
|
+
var EXPIRING_SOON_MS = 7 * 24 * 60 * 60 * 1e3;
|
|
49
|
+
function detectSocialToken(home, file, idKey, tokenKey) {
|
|
50
|
+
const cfg = readJson(home, file);
|
|
51
|
+
const id = cfg?.[idKey];
|
|
52
|
+
const token = cfg?.[tokenKey];
|
|
53
|
+
if (typeof id !== "string" || !id || typeof token !== "string" || !token) {
|
|
54
|
+
return { present: false };
|
|
55
|
+
}
|
|
56
|
+
const display = typeof cfg.username === "string" && cfg.username || typeof cfg.pageName === "string" && cfg.pageName || id;
|
|
57
|
+
const expiresAt = typeof cfg.expiresAt === "string" ? Date.parse(cfg.expiresAt) : NaN;
|
|
58
|
+
if (!Number.isFinite(expiresAt)) return { present: true, detail: display };
|
|
59
|
+
const remainingMs = expiresAt - Date.now();
|
|
60
|
+
if (remainingMs <= 0) {
|
|
61
|
+
return { present: true, detail: display, freshness: "expired", daysRemaining: 0 };
|
|
62
|
+
}
|
|
63
|
+
const daysRemaining = Math.max(1, Math.ceil(remainingMs / 864e5));
|
|
64
|
+
if (remainingMs <= EXPIRING_SOON_MS) {
|
|
65
|
+
return { present: true, detail: display, freshness: "expiring", daysRemaining };
|
|
66
|
+
}
|
|
67
|
+
return { present: true, detail: display, freshness: "fresh", daysRemaining };
|
|
68
|
+
}
|
|
48
69
|
function hasPlaySa(home) {
|
|
49
70
|
if (hasFile(home, "play-service-account.json")) return true;
|
|
50
71
|
try {
|
|
@@ -365,10 +386,7 @@ var CREDENTIALS = [
|
|
|
365
386
|
]
|
|
366
387
|
},
|
|
367
388
|
docsAnchor: "facebook",
|
|
368
|
-
detect: (home) =>
|
|
369
|
-
const cfg = readJson(home, "facebook.json");
|
|
370
|
-
return cfg?.pageId ? { present: true, detail: cfg.pageName ?? cfg.pageId } : { present: false };
|
|
371
|
-
}
|
|
389
|
+
detect: (home) => detectSocialToken(home, "facebook.json", "pageId", "pageAccessToken")
|
|
372
390
|
},
|
|
373
391
|
{
|
|
374
392
|
id: "instagram",
|
|
@@ -396,10 +414,37 @@ var CREDENTIALS = [
|
|
|
396
414
|
]
|
|
397
415
|
},
|
|
398
416
|
docsAnchor: "instagram",
|
|
399
|
-
detect: (home) =>
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
417
|
+
detect: (home) => detectSocialToken(home, "instagram.json", "userId", "accessToken")
|
|
418
|
+
},
|
|
419
|
+
{
|
|
420
|
+
id: "threads",
|
|
421
|
+
label: {
|
|
422
|
+
ko: "Threads",
|
|
423
|
+
en: "Threads"
|
|
424
|
+
},
|
|
425
|
+
requirement: "optional",
|
|
426
|
+
group: "marketing",
|
|
427
|
+
file: "~/.mimi-seed/threads.json",
|
|
428
|
+
fix: "mimi-seed auth threads",
|
|
429
|
+
setup: { kind: "mcp-bin", bin: "mimi-seed-social-auth", args: ["threads"] },
|
|
430
|
+
obtain: {
|
|
431
|
+
ko: [
|
|
432
|
+
"Instagram \uACFC **\uBCC4\uAC1C \uACC4\uC815\xB7\uBCC4\uAC1C \uD1A0\uD070**\uC774\uB2E4 (Threads Graph API).",
|
|
433
|
+
"developers.facebook.com \u2192 \uC571 \u2192 Threads API use case \uCD94\uAC00",
|
|
434
|
+
"\u2192 \uAD8C\uD55C threads_basic, threads_content_publish",
|
|
435
|
+
"\u2192 Threads \uB85C\uADF8\uC778\uC73C\uB85C authorize \u2192 long-lived \uD1A0\uD070 \uAD50\uD658 (\uC57D 60\uC77C).",
|
|
436
|
+
"userId \uB294 \uD1A0\uD070\uC5D0\uC11C \uC790\uB3D9 \uC870\uD68C\uB41C\uB2E4."
|
|
437
|
+
],
|
|
438
|
+
en: [
|
|
439
|
+
"A **separate account and token** from Instagram (Threads Graph API).",
|
|
440
|
+
"developers.facebook.com \u2192 your app \u2192 add the Threads API use case",
|
|
441
|
+
"\u2192 permissions threads_basic, threads_content_publish",
|
|
442
|
+
"\u2192 authorize with Threads login \u2192 exchange for a long-lived token (~60 days).",
|
|
443
|
+
"userId is looked up from the token."
|
|
444
|
+
]
|
|
445
|
+
},
|
|
446
|
+
docsAnchor: "threads",
|
|
447
|
+
detect: (home) => detectSocialToken(home, "threads.json", "userId", "accessToken")
|
|
403
448
|
},
|
|
404
449
|
{
|
|
405
450
|
id: "anthropic",
|
|
@@ -457,7 +502,9 @@ function planSetup(detected, opts = {}) {
|
|
|
457
502
|
return CREDENTIALS.filter((spec) => {
|
|
458
503
|
if (only && !only.has(spec.id)) return false;
|
|
459
504
|
if (reconnect.has(spec.id)) return true;
|
|
460
|
-
|
|
505
|
+
const found = detected.get(spec.id);
|
|
506
|
+
if (found?.freshness === "expired" || found?.freshness === "expiring") return true;
|
|
507
|
+
if (found?.present) return false;
|
|
461
508
|
if (spec.requirement === "platform" && platforms.length > 0 && !platforms.includes(spec.platform)) {
|
|
462
509
|
return false;
|
|
463
510
|
}
|
|
@@ -1384,7 +1431,7 @@ async function cmdDeploy(argv) {
|
|
|
1384
1431
|
}
|
|
1385
1432
|
let appId = args.appId;
|
|
1386
1433
|
if (!appId) {
|
|
1387
|
-
const { mcpCall } = await import("./mcp-client-
|
|
1434
|
+
const { mcpCall } = await import("./mcp-client-DQBKWHT4.js");
|
|
1388
1435
|
const r = await mcpCall(cfg.endpoint, cfg.token, "list_apps", {});
|
|
1389
1436
|
if (!r.isError) {
|
|
1390
1437
|
try {
|
|
@@ -1475,11 +1522,13 @@ function statusLine(spec, detected, platforms) {
|
|
|
1475
1522
|
const d = detected.get(spec.id);
|
|
1476
1523
|
const relevant = spec.requirement !== "platform" || platforms.length === 0 || platforms.includes(spec.platform);
|
|
1477
1524
|
let mark;
|
|
1478
|
-
if (d.
|
|
1525
|
+
if (d.freshness === "expired") mark = kleur2.red("\u2717");
|
|
1526
|
+
else if (d.freshness === "expiring") mark = kleur2.yellow("!");
|
|
1527
|
+
else if (d.present) mark = kleur2.green("\u2713");
|
|
1479
1528
|
else if (isSatisfied(spec, detected)) mark = kleur2.yellow("~");
|
|
1480
1529
|
else if (spec.requirement === "optional" || !relevant) mark = kleur2.dim("\xB7");
|
|
1481
1530
|
else mark = kleur2.red("\u2717");
|
|
1482
|
-
const tail = d.present ? kleur2.dim(d.detail ?? "") : isSatisfied(spec, detected) ? kleur2.dim(`${credNote(spec) ?? t().setup.fallbackWorking}`) : kleur2.dim(`\u2192 ${spec.fix}`);
|
|
1531
|
+
const tail = d.freshness === "expired" ? kleur2.red(`${t().setup.tokenExpired} \u2192 ${spec.fix}`) : d.freshness === "expiring" ? kleur2.yellow(`${t().setup.tokenExpiring(d.daysRemaining ?? 0)} \u2192 ${spec.fix}`) : d.present ? kleur2.dim(d.detail ?? "") : isSatisfied(spec, detected) ? kleur2.dim(`${credNote(spec) ?? t().setup.fallbackWorking}`) : kleur2.dim(`\u2192 ${spec.fix}`);
|
|
1483
1532
|
return ` ${mark} ${credLabel(spec).padEnd(24)} ${tail}`;
|
|
1484
1533
|
}
|
|
1485
1534
|
function printStatus(detected, platforms) {
|
|
@@ -78,6 +78,8 @@ var ko = {
|
|
|
78
78
|
runInTerminal: " \uB300\uD654\uD615\uC73C\uB85C \uC5F0\uACB0\uD558\uB824\uBA74 \uD130\uBBF8\uB110\uC5D0\uC11C: mimi-seed setup",
|
|
79
79
|
onlyAlreadyDone: " \u2705 \uC694\uCCAD\uD55C \uD56D\uBAA9\uC740 \uC774\uBBF8 \uC5F0\uACB0\uB3FC \uC788\uC5B4.",
|
|
80
80
|
onlyReconnectHint: " \uB2E4\uC2DC \uC124\uC815\uD558\uB824\uBA74: mimi-seed setup --reconnect <id>",
|
|
81
|
+
tokenExpired: "\uD1A0\uD070 \uB9CC\uB8CC \u2014 \uB2E4\uC2DC \uC5F0\uACB0 \uD544\uC694",
|
|
82
|
+
tokenExpiring: (days) => `\uD1A0\uD070 ${days}\uC77C \uD6C4 \uB9CC\uB8CC \u2014 \uC9C0\uAE08 \uAC31\uC2E0 \uAD8C\uC7A5`,
|
|
81
83
|
allDone: " \u2705 \uC5F0\uACB0\uD560 \uAC8C \uB354 \uC5C6\uC5B4. \uB2E4 \uB410\uB2E4.",
|
|
82
84
|
planCount: (n) => ` ${n}\uAC1C \uD56D\uBAA9\uC744 \uC21C\uC11C\uB300\uB85C \uBB3C\uC5B4\uBCFC\uAC8C. \uC5B8\uC81C\uB4E0 s=\uAC74\uB108\uB6F0\uAE30, q=\uC885\uB8CC.`,
|
|
83
85
|
prompt: " [c] \uC5F0\uACB0 [s] \uAC74\uB108\uB6F0\uAE30 [?] \uC774\uAC74 \uC5B4\uB5BB\uAC8C \uAD6C\uD558\uB098\uC694 [q] \uC885\uB8CC : ",
|
|
@@ -177,6 +179,8 @@ MIMI_SEED_LANG takes precedence when set.`,
|
|
|
177
179
|
runInTerminal: " To connect interactively, run: mimi-seed setup",
|
|
178
180
|
onlyAlreadyDone: " \u2705 What you asked for is already connected.",
|
|
179
181
|
onlyReconnectHint: " To redo it: mimi-seed setup --reconnect <id>",
|
|
182
|
+
tokenExpired: "token expired \u2014 reconnect required",
|
|
183
|
+
tokenExpiring: (days) => `token expires in ${days} day(s) \u2014 refresh now`,
|
|
180
184
|
allDone: " \u2705 Nothing left to connect. You're set.",
|
|
181
185
|
planCount: (n) => ` I'll walk you through ${n} item(s). s = skip, q = quit, anytime.`,
|
|
182
186
|
prompt: " [c] connect [s] skip [?] how do I get this [q] quit : ",
|
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
mcpCall
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-HCCOWX3G.js";
|
|
5
5
|
import {
|
|
6
6
|
CONFIG_LOCATION,
|
|
7
7
|
CREDENTIALS,
|
|
@@ -20,14 +20,14 @@ import {
|
|
|
20
20
|
runMcpBin,
|
|
21
21
|
tryCredById,
|
|
22
22
|
writeConfig
|
|
23
|
-
} from "./chunk-
|
|
23
|
+
} from "./chunk-PL7N2FSO.js";
|
|
24
24
|
import {
|
|
25
25
|
catalog,
|
|
26
26
|
isLang,
|
|
27
27
|
resolveLang,
|
|
28
28
|
t,
|
|
29
29
|
writeSettings
|
|
30
|
-
} from "./chunk-
|
|
30
|
+
} from "./chunk-VZQHUWXR.js";
|
|
31
31
|
|
|
32
32
|
// src/index.ts
|
|
33
33
|
import os3 from "os";
|
|
@@ -983,11 +983,13 @@ ${kleur5.bold("\uD50C\uB7AB\uD3FC\uBCC4 \uC790\uACA9\uC99D\uBA85:")}
|
|
|
983
983
|
${kleur5.cyan("mimi-seed auth bigquery")} BigQuery \uC11C\uBE44\uC2A4 \uACC4\uC815 (Crashlytics export \uB4F1)
|
|
984
984
|
|
|
985
985
|
${kleur5.bold("\uBE4C\uB4DC / \uB9C8\uCF00\uD305:")}
|
|
986
|
+
${kleur5.cyan("mimi-seed auth meta")} Facebook \xB7 Instagram \xB7 Threads \uD55C \uBC88\uC5D0
|
|
986
987
|
${kleur5.cyan("mimi-seed auth jenkins")} Jenkins \uC5F0\uACB0 (jenkins.json)
|
|
987
988
|
${kleur5.cyan("mimi-seed auth ci")} GitHub Actions / GitLab CI (ci.json)
|
|
988
989
|
${kleur5.cyan("mimi-seed auth googleads")} Google Ads (google-ads.json)
|
|
989
990
|
${kleur5.cyan("mimi-seed auth facebook")} Facebook \uD398\uC774\uC9C0
|
|
990
991
|
${kleur5.cyan("mimi-seed auth instagram")} Instagram
|
|
992
|
+
${kleur5.cyan("mimi-seed auth threads")} Threads
|
|
991
993
|
|
|
992
994
|
${kleur5.bold("\uC804\uCCB4 \uC0C1\uD0DC:")}
|
|
993
995
|
${kleur5.cyan("mimi-seed auth status --all")} \uBAA8\uB4E0 \uC790\uACA9\uC99D\uBA85 \uBCF4\uC720 \uC5EC\uBD80 \uD55C\uB208\uC5D0
|
|
@@ -1018,11 +1020,13 @@ ${kleur5.bold("Per-platform credentials:")}
|
|
|
1018
1020
|
${kleur5.cyan("mimi-seed auth bigquery")} BigQuery service account (Crashlytics export, etc.)
|
|
1019
1021
|
|
|
1020
1022
|
${kleur5.bold("Build / marketing:")}
|
|
1023
|
+
${kleur5.cyan("mimi-seed auth meta")} Facebook \xB7 Instagram \xB7 Threads in one flow
|
|
1021
1024
|
${kleur5.cyan("mimi-seed auth jenkins")} Jenkins connection (jenkins.json)
|
|
1022
1025
|
${kleur5.cyan("mimi-seed auth ci")} GitHub Actions / GitLab CI (ci.json)
|
|
1023
1026
|
${kleur5.cyan("mimi-seed auth googleads")} Google Ads (google-ads.json)
|
|
1024
1027
|
${kleur5.cyan("mimi-seed auth facebook")} Facebook Page
|
|
1025
1028
|
${kleur5.cyan("mimi-seed auth instagram")} Instagram
|
|
1029
|
+
${kleur5.cyan("mimi-seed auth threads")} Threads
|
|
1026
1030
|
|
|
1027
1031
|
${kleur5.bold("Everything at a glance:")}
|
|
1028
1032
|
${kleur5.cyan("mimi-seed auth status --all")} which credentials you have
|
|
@@ -1047,8 +1051,8 @@ function printAllCredStatus() {
|
|
|
1047
1051
|
const detected = detectAll();
|
|
1048
1052
|
for (const spec of CREDENTIALS) {
|
|
1049
1053
|
const d = detected.get(spec.id);
|
|
1050
|
-
const mark = d.present ? kleur5.green("\u2713") : isSatisfied(spec, detected) ? kleur5.yellow("~") : spec.requirement === "optional" ? kleur5.dim("\xB7") : kleur5.red("\u2717");
|
|
1051
|
-
const tail = d.present ? kleur5.dim(d.detail ?? "") : kleur5.dim(`\u2192 ${spec.fix}`);
|
|
1054
|
+
const mark = d.freshness === "expired" ? kleur5.red("\u2717") : d.freshness === "expiring" ? kleur5.yellow("!") : d.present ? kleur5.green("\u2713") : isSatisfied(spec, detected) ? kleur5.yellow("~") : spec.requirement === "optional" ? kleur5.dim("\xB7") : kleur5.red("\u2717");
|
|
1055
|
+
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}`);
|
|
1052
1056
|
log(` ${mark} ${credLabel(spec).padEnd(24)} ${tail}`);
|
|
1053
1057
|
}
|
|
1054
1058
|
log(kleur5.dim(M5().connectAll));
|
|
@@ -1069,10 +1073,12 @@ async function cmdAuth(args) {
|
|
|
1069
1073
|
if (sub === "bigquery") return void exitWith(await runMcpBin("mimi-seed-bigquery-auth", rest));
|
|
1070
1074
|
if (sub === "jenkins") return void exitWith(await runMcpBin("mimi-seed-jenkins-auth", rest));
|
|
1071
1075
|
if (sub === "googleads") return void exitWith(await runMcpBin("mimi-seed-googleads-auth", rest));
|
|
1076
|
+
if (sub === "meta") return void exitWith(await runMcpBin("mimi-seed-social-auth", ["all"]));
|
|
1072
1077
|
if (sub === "facebook") return void exitWith(await runMcpBin("mimi-seed-social-auth", ["facebook"]));
|
|
1073
1078
|
if (sub === "instagram") return void exitWith(await runMcpBin("mimi-seed-social-auth", ["instagram"]));
|
|
1079
|
+
if (sub === "threads") return void exitWith(await runMcpBin("mimi-seed-social-auth", ["threads"]));
|
|
1074
1080
|
if (sub === "ci") {
|
|
1075
|
-
const { cmdSetup: cmdSetup2 } = await import("./setup-
|
|
1081
|
+
const { cmdSetup: cmdSetup2 } = await import("./setup-EQVJO6F7.js");
|
|
1076
1082
|
await cmdSetup2(["--only", "github,gitlab", "--reconnect", "github,gitlab"]);
|
|
1077
1083
|
return;
|
|
1078
1084
|
}
|