@prbartosh/poczta-mcp 0.1.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/.env.example +19 -0
- package/LICENSE +21 -0
- package/README.md +141 -0
- package/config.example.json +50 -0
- package/cron.example +19 -0
- package/dist/auth/google.js +29 -0
- package/dist/auth/google.js.map +1 -0
- package/dist/auth/index.js +31 -0
- package/dist/auth/index.js.map +1 -0
- package/dist/auth/microsoft.js +44 -0
- package/dist/auth/microsoft.js.map +1 -0
- package/dist/config.js +201 -0
- package/dist/config.js.map +1 -0
- package/dist/digest.js +82 -0
- package/dist/digest.js.map +1 -0
- package/dist/index.js +105 -0
- package/dist/index.js.map +1 -0
- package/dist/install.js +209 -0
- package/dist/install.js.map +1 -0
- package/dist/mail/imap.js +192 -0
- package/dist/mail/imap.js.map +1 -0
- package/dist/mail/smtp.js +50 -0
- package/dist/mail/smtp.js.map +1 -0
- package/dist/oauth.js +138 -0
- package/dist/oauth.js.map +1 -0
- package/dist/server.js +201 -0
- package/dist/server.js.map +1 -0
- package/dist/setup.js +444 -0
- package/dist/setup.js.map +1 -0
- package/package.json +62 -0
- package/skills/daily-briefing/SKILL.md +57 -0
package/dist/setup.js
ADDED
|
@@ -0,0 +1,444 @@
|
|
|
1
|
+
import { existsSync, readFileSync, writeFileSync } from "node:fs";
|
|
2
|
+
import { resolve } from "node:path";
|
|
3
|
+
import { intro, outro, text, password, select, multiselect, confirm, isCancel, cancel, note, spinner, log, } from "@clack/prompts";
|
|
4
|
+
import { configSchema, loadEnv } from "./config.js";
|
|
5
|
+
import { googleLoopback, microsoftLoopback } from "./oauth.js";
|
|
6
|
+
// Silver ASCII banner shown at launch.
|
|
7
|
+
const SILVER = "\x1b[1;38;5;250m";
|
|
8
|
+
const RESET = "\x1b[0m";
|
|
9
|
+
const BANNER_MAIL = [
|
|
10
|
+
"███╗ ███╗ █████╗ ██╗██╗ ",
|
|
11
|
+
"████╗ ████║██╔══██╗██║██║ ",
|
|
12
|
+
"██╔████╔██║███████║██║██║ ",
|
|
13
|
+
"██║╚██╔╝██║██╔══██║██║██║ ",
|
|
14
|
+
"██║ ╚═╝ ██║██║ ██║██║███████╗",
|
|
15
|
+
"╚═╝ ╚═╝╚═╝ ╚═╝╚═╝╚══════╝",
|
|
16
|
+
];
|
|
17
|
+
const BANNER_MCP = [
|
|
18
|
+
"███╗ ███╗ ██████╗██████╗ ",
|
|
19
|
+
"████╗ ████║██╔════╝██╔══██╗",
|
|
20
|
+
"██╔████╔██║██║ ██████╔╝",
|
|
21
|
+
"██║╚██╔╝██║██║ ██╔═══╝ ",
|
|
22
|
+
"██║ ╚═╝ ██║╚██████╗██║ ",
|
|
23
|
+
"╚═╝ ╚═╝ ╚═════╝╚═╝ ",
|
|
24
|
+
];
|
|
25
|
+
function banner() {
|
|
26
|
+
process.stdout.write("\n");
|
|
27
|
+
for (let i = 0; i < BANNER_MAIL.length; i++) {
|
|
28
|
+
process.stdout.write(`${SILVER}${BANNER_MAIL[i]} ${BANNER_MCP[i]}${RESET}\n`);
|
|
29
|
+
}
|
|
30
|
+
process.stdout.write("\n");
|
|
31
|
+
}
|
|
32
|
+
/** Read+validate an existing config.json (secrets not required). Null if absent/invalid. */
|
|
33
|
+
function loadExistingConfig() {
|
|
34
|
+
const p = resolve(process.cwd(), "config.json");
|
|
35
|
+
if (!existsSync(p))
|
|
36
|
+
return null;
|
|
37
|
+
try {
|
|
38
|
+
const parsed = configSchema.safeParse(JSON.parse(readFileSync(p, "utf8")));
|
|
39
|
+
return parsed.success ? parsed.data : null;
|
|
40
|
+
}
|
|
41
|
+
catch {
|
|
42
|
+
return null;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
function summary(cfg) {
|
|
46
|
+
const accs = cfg.accounts
|
|
47
|
+
.map((a) => `• ${a.id} — ${a.email} [${a.auth.type === "password" ? "password" : "oauth2:" + a.auth.provider}]`)
|
|
48
|
+
.join("\n") || "(brak)";
|
|
49
|
+
const chs = cfg.digest.channels
|
|
50
|
+
.map((c) => c.type === "email"
|
|
51
|
+
? `• email -> ${c.to} (z ${c.fromAccount})`
|
|
52
|
+
: c.type === "file"
|
|
53
|
+
? `• plik -> ${c.path}`
|
|
54
|
+
: c.type === "webhook"
|
|
55
|
+
? `• webhook (${c.format})`
|
|
56
|
+
: "• czat")
|
|
57
|
+
.join("\n") || "(brak)";
|
|
58
|
+
return `Konta:\n${accs}\n\nKanaly podsumowania:\n${chs}`;
|
|
59
|
+
}
|
|
60
|
+
/** Build the digest channels list (used in fresh setup and when editing). */
|
|
61
|
+
async function configureChannels(accounts, secrets) {
|
|
62
|
+
const picked = req(await multiselect({
|
|
63
|
+
message: "Kanaly podsumowania (spacja zaznacza)",
|
|
64
|
+
options: [
|
|
65
|
+
{ value: "chat", label: "Czat / output agenta", hint: "domyslny" },
|
|
66
|
+
{ value: "file", label: "Plik markdown" },
|
|
67
|
+
{ value: "email", label: "Mail z podsumowaniem" },
|
|
68
|
+
{ value: "webhook", label: "Webhook (Slack/Teams)" },
|
|
69
|
+
],
|
|
70
|
+
initialValues: ["chat"],
|
|
71
|
+
required: false,
|
|
72
|
+
}));
|
|
73
|
+
const channels = [];
|
|
74
|
+
if (picked.includes("chat") || picked.length === 0)
|
|
75
|
+
channels.push({ type: "chat" });
|
|
76
|
+
if (picked.includes("file")) {
|
|
77
|
+
const path = req(await text({
|
|
78
|
+
message: "Sciezka pliku (placeholder {date})",
|
|
79
|
+
placeholder: "~/poczta-digest/{date}.md",
|
|
80
|
+
defaultValue: "~/poczta-digest/{date}.md",
|
|
81
|
+
}));
|
|
82
|
+
channels.push({ type: "file", path });
|
|
83
|
+
}
|
|
84
|
+
if (picked.includes("email")) {
|
|
85
|
+
const to = req(await text({ message: "Adres odbiorcy digestu" })).trim();
|
|
86
|
+
const fromAccount = req(await select({
|
|
87
|
+
message: "Konto nadawcy digestu",
|
|
88
|
+
options: accounts.map((a) => ({ value: a.id, label: `${a.label ?? a.id} (${a.email})` })),
|
|
89
|
+
}));
|
|
90
|
+
channels.push({ type: "email", to, fromAccount, subject: "Codzienny przeglad poczty {date}" });
|
|
91
|
+
}
|
|
92
|
+
if (picked.includes("webhook")) {
|
|
93
|
+
const urlKey = "DIGEST_WEBHOOK_URL";
|
|
94
|
+
const url = req(await password({ message: "URL webhooka" }));
|
|
95
|
+
secrets.set(urlKey, url);
|
|
96
|
+
process.env[urlKey] = url;
|
|
97
|
+
const format = req(await select({
|
|
98
|
+
message: "Format webhooka",
|
|
99
|
+
options: [
|
|
100
|
+
{ value: "slack", label: "Slack/Teams ({text})" },
|
|
101
|
+
{ value: "raw", label: "Raw JSON ({markdown,date})" },
|
|
102
|
+
],
|
|
103
|
+
}));
|
|
104
|
+
channels.push({ type: "webhook", urlEnv: urlKey, format });
|
|
105
|
+
}
|
|
106
|
+
return channels;
|
|
107
|
+
}
|
|
108
|
+
/** Validate + persist config.json and merge secrets into .env. Exits on invalid config. */
|
|
109
|
+
function writeAll(cfg, secrets) {
|
|
110
|
+
const parsed = configSchema.safeParse(cfg);
|
|
111
|
+
if (!parsed.success) {
|
|
112
|
+
cancel("Config niepoprawny:\n" + JSON.stringify(parsed.error.issues, null, 2));
|
|
113
|
+
process.exit(1);
|
|
114
|
+
}
|
|
115
|
+
const cfgPath = resolve(process.cwd(), "config.json");
|
|
116
|
+
const envP = resolve(process.cwd(), ".env");
|
|
117
|
+
writeFileSync(cfgPath, JSON.stringify(parsed.data, null, 2) + "\n", "utf8");
|
|
118
|
+
let envContent = existsSync(envP) ? readFileSync(envP, "utf8") : "";
|
|
119
|
+
for (const [k, v] of secrets)
|
|
120
|
+
envContent = upsertEnv(envContent, k, v);
|
|
121
|
+
writeFileSync(envP, envContent, "utf8");
|
|
122
|
+
return { cfgPath, envP };
|
|
123
|
+
}
|
|
124
|
+
/** Connection check per account (auth + folder list). Uses process.env (loaded + in-memory). */
|
|
125
|
+
async function runTest(cfg) {
|
|
126
|
+
const { listFolders } = await import("./mail/imap.js");
|
|
127
|
+
for (const acc of cfg.accounts) {
|
|
128
|
+
const s = spinner();
|
|
129
|
+
s.start(`${acc.id} (${acc.email})`);
|
|
130
|
+
try {
|
|
131
|
+
const folders = await listFolders(acc);
|
|
132
|
+
s.stop(`OK ${acc.id} — ${folders.length} folderow`);
|
|
133
|
+
}
|
|
134
|
+
catch (e) {
|
|
135
|
+
s.stop(`FAIL ${acc.id} — ${e.message}`);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Interactive wizard (clack UI). Writes:
|
|
141
|
+
* ./config.json -> structure (no secrets, only env-var NAMES)
|
|
142
|
+
* ./.env -> secret values (git-ignored)
|
|
143
|
+
*
|
|
144
|
+
* Secrets are masked on entry. OAuth tokens/client secrets are pasted in; see README.
|
|
145
|
+
*/
|
|
146
|
+
const PRESETS = {
|
|
147
|
+
agh: { imap: ["poczta.agh.edu.pl", 993], smtp: ["poczta.agh.edu.pl", 465, true] },
|
|
148
|
+
gmail: { imap: ["imap.gmail.com", 993], smtp: ["smtp.gmail.com", 465, true] },
|
|
149
|
+
m365: { imap: ["outlook.office365.com", 993], smtp: ["smtp.office365.com", 587, false] },
|
|
150
|
+
};
|
|
151
|
+
/** Await a clack prompt; on Ctrl+C abort the whole wizard cleanly. */
|
|
152
|
+
function req(value) {
|
|
153
|
+
if (isCancel(value)) {
|
|
154
|
+
cancel("Przerwano. Nic nie zapisano.");
|
|
155
|
+
process.exit(0);
|
|
156
|
+
}
|
|
157
|
+
return value;
|
|
158
|
+
}
|
|
159
|
+
function envKey(id, suffix) {
|
|
160
|
+
return `${id.toUpperCase().replace(/[^A-Z0-9]/g, "_")}_${suffix}`;
|
|
161
|
+
}
|
|
162
|
+
function upsertEnv(content, key, value) {
|
|
163
|
+
const line = `${key}=${value}`;
|
|
164
|
+
const re = new RegExp(`^${key}=.*$`, "m");
|
|
165
|
+
if (re.test(content))
|
|
166
|
+
return content.replace(re, line);
|
|
167
|
+
return content.replace(/\n*$/, "\n") + line + "\n";
|
|
168
|
+
}
|
|
169
|
+
async function addAccount(takenIds) {
|
|
170
|
+
const secrets = new Map();
|
|
171
|
+
const id = req(await text({
|
|
172
|
+
message: "id konta (klucz techniczny: w komendach i nazwach zmiennych)",
|
|
173
|
+
placeholder: "agh / gmail / firma",
|
|
174
|
+
validate: (v) => {
|
|
175
|
+
const s = (v ?? "").trim().toLowerCase();
|
|
176
|
+
if (!s)
|
|
177
|
+
return "wymagane";
|
|
178
|
+
if (!/^[a-z0-9_-]+$/.test(s))
|
|
179
|
+
return "tylko male litery, cyfry, _ i -";
|
|
180
|
+
if (takenIds.has(s))
|
|
181
|
+
return "id juz uzyte";
|
|
182
|
+
return undefined;
|
|
183
|
+
},
|
|
184
|
+
})).trim().toLowerCase();
|
|
185
|
+
const label = req(await text({
|
|
186
|
+
message: "etykieta (nazwa dla czlowieka, w podsumowaniach)",
|
|
187
|
+
placeholder: id,
|
|
188
|
+
defaultValue: id,
|
|
189
|
+
}));
|
|
190
|
+
const email = req(await text({
|
|
191
|
+
message: "adres email",
|
|
192
|
+
validate: (v) => (/^[^@\s]+@[^@\s]+\.[^@\s]+$/.test((v ?? "").trim()) ? undefined : "niepoprawny email"),
|
|
193
|
+
})).trim();
|
|
194
|
+
const provider = req(await select({
|
|
195
|
+
message: "dostawca / typ logowania",
|
|
196
|
+
options: [
|
|
197
|
+
{ value: "generic", label: "Generic IMAP / app-password", hint: "AGH, firmowe IMAP" },
|
|
198
|
+
{ value: "gmail", label: "Gmail", hint: "OAuth2" },
|
|
199
|
+
{ value: "m365", label: "Microsoft 365 / Outlook", hint: "OAuth2" },
|
|
200
|
+
],
|
|
201
|
+
}));
|
|
202
|
+
let imapHost, imapPort, smtpHost, smtpPort, smtpSecure;
|
|
203
|
+
let auth;
|
|
204
|
+
if (provider === "gmail") {
|
|
205
|
+
[imapHost, imapPort] = PRESETS.gmail.imap;
|
|
206
|
+
[smtpHost, smtpPort, smtpSecure] = PRESETS.gmail.smtp;
|
|
207
|
+
const method = req(await select({
|
|
208
|
+
message: "Metoda logowania Gmail",
|
|
209
|
+
options: [
|
|
210
|
+
{ value: "app", label: "App-password (najprostsze)", hint: "email + 16-znakowe haslo, wymaga 2FA" },
|
|
211
|
+
{ value: "oauth", label: "OAuth2", hint: "clientId/secret + przegladarka" },
|
|
212
|
+
],
|
|
213
|
+
initialValue: "app",
|
|
214
|
+
}));
|
|
215
|
+
if (method === "app") {
|
|
216
|
+
note("1. myaccount.google.com -> Bezpieczenstwo -> wlacz weryfikacje 2-etapowa\n" +
|
|
217
|
+
"2. Haslo do aplikacji (App passwords) -> wybierz Mail -> skopiuj 16 znakow\n" +
|
|
218
|
+
"3. w Gmailu wlacz IMAP (Ustawienia -> Przekazywanie i POP/IMAP)\n" +
|
|
219
|
+
"Uwaga: to NIE jest zwykle haslo do konta, tylko app-password.", "Gmail app-password");
|
|
220
|
+
const pKey = envKey(id, "PASSWORD");
|
|
221
|
+
secrets.set(pKey, req(await password({ message: "Gmail app-password (16 znakow)" })));
|
|
222
|
+
auth = { type: "password", passwordEnv: pKey };
|
|
223
|
+
return {
|
|
224
|
+
account: {
|
|
225
|
+
id,
|
|
226
|
+
label,
|
|
227
|
+
email,
|
|
228
|
+
imap: { host: imapHost, port: imapPort, secure: imapPort === 993 },
|
|
229
|
+
smtp: { host: smtpHost, port: smtpPort, secure: smtpSecure },
|
|
230
|
+
auth,
|
|
231
|
+
},
|
|
232
|
+
secrets,
|
|
233
|
+
};
|
|
234
|
+
}
|
|
235
|
+
note("1. console.cloud.google.com -> projekt\n" +
|
|
236
|
+
"2. OAuth consent screen: dodaj siebie jako Test user + scope https://mail.google.com/\n" +
|
|
237
|
+
"3. Credentials -> Create -> OAuth client ID -> typ 'Desktop app'\n" +
|
|
238
|
+
"4. skopiuj Client ID (konczy sie .apps.googleusercontent.com) i Client secret\n" +
|
|
239
|
+
"5. w Gmailu wlacz IMAP (Ustawienia -> Przekazywanie i POP/IMAP)", "Gmail: skad clientId/secret");
|
|
240
|
+
const clientId = req(await text({ message: "Google Client ID", placeholder: "1234-abc.apps.googleusercontent.com" })).trim();
|
|
241
|
+
const csKey = envKey(id, "CLIENT_SECRET");
|
|
242
|
+
const rtKey = envKey(id, "REFRESH_TOKEN");
|
|
243
|
+
const clientSecret = req(await password({ message: "Google Client secret" }));
|
|
244
|
+
secrets.set(csKey, clientSecret);
|
|
245
|
+
const auto = req(await confirm({ message: "Zdobyc refresh token teraz (otworze przegladarke)?", initialValue: true }));
|
|
246
|
+
if (auto) {
|
|
247
|
+
const s = spinner();
|
|
248
|
+
s.start("Czekam na zgode w przegladarce...");
|
|
249
|
+
try {
|
|
250
|
+
const { refreshToken } = await googleLoopback({ clientId, clientSecret });
|
|
251
|
+
secrets.set(rtKey, refreshToken);
|
|
252
|
+
s.stop("Refresh token zdobyty.");
|
|
253
|
+
}
|
|
254
|
+
catch (e) {
|
|
255
|
+
s.stop("Auto nieudane: " + e.message);
|
|
256
|
+
secrets.set(rtKey, req(await password({ message: "Wklej refresh token recznie" })));
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
else {
|
|
260
|
+
secrets.set(rtKey, req(await password({ message: "Google refresh token" })));
|
|
261
|
+
}
|
|
262
|
+
auth = { type: "oauth2", provider: "google", clientId, clientSecretEnv: csKey, refreshTokenEnv: rtKey };
|
|
263
|
+
}
|
|
264
|
+
else if (provider === "m365") {
|
|
265
|
+
[imapHost, imapPort] = PRESETS.m365.imap;
|
|
266
|
+
[smtpHost, smtpPort, smtpSecure] = PRESETS.m365.smtp;
|
|
267
|
+
note("outlook.office365.com:993 · smtp.office365.com:587 (STARTTLS)\n" +
|
|
268
|
+
"Azure Portal -> Entra ID -> App registrations -> New registration.\n" +
|
|
269
|
+
"tenantId i clientId sa na stronie aplikacji (Overview), secret w Certificates & secrets.", "Microsoft 365: skad dane");
|
|
270
|
+
const tenantId = req(await text({ message: "Azure tenantId" })).trim();
|
|
271
|
+
const clientId = req(await text({ message: "Azure app clientId" })).trim();
|
|
272
|
+
const csKey = envKey(id, "CLIENT_SECRET");
|
|
273
|
+
const clientSecret = req(await password({ message: "Azure client secret" }));
|
|
274
|
+
secrets.set(csKey, clientSecret);
|
|
275
|
+
const flow = req(await select({
|
|
276
|
+
message: "flow OAuth2",
|
|
277
|
+
options: [
|
|
278
|
+
{ value: "refresh", label: "refresh (delegowany)", hint: "zgoda raz, refresh token" },
|
|
279
|
+
{ value: "client_credentials", label: "client_credentials (app-only)", hint: "automat, wymaga admina + ApplicationAccessPolicy" },
|
|
280
|
+
],
|
|
281
|
+
}));
|
|
282
|
+
if (flow === "refresh") {
|
|
283
|
+
const rtKey = envKey(id, "REFRESH_TOKEN");
|
|
284
|
+
note("Auto-token wymaga w Azure: Authentication -> Add platform -> 'Mobile and desktop applications' -> redirect http://localhost:3000\n" +
|
|
285
|
+
"Oraz API permissions (delegated): IMAP.AccessAsUser.All, SMTP.Send, offline_access.", "M365 refresh token");
|
|
286
|
+
const auto = req(await confirm({ message: "Zdobyc refresh token teraz (przegladarka, port 3000)?", initialValue: true }));
|
|
287
|
+
if (auto) {
|
|
288
|
+
const s = spinner();
|
|
289
|
+
s.start("Czekam na zgode w przegladarce...");
|
|
290
|
+
try {
|
|
291
|
+
const { refreshToken } = await microsoftLoopback({ tenantId, clientId, clientSecret, port: 3000 });
|
|
292
|
+
secrets.set(rtKey, refreshToken);
|
|
293
|
+
s.stop("Refresh token zdobyty.");
|
|
294
|
+
}
|
|
295
|
+
catch (e) {
|
|
296
|
+
s.stop("Auto nieudane: " + e.message);
|
|
297
|
+
secrets.set(rtKey, req(await password({ message: "Wklej refresh token recznie" })));
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
else {
|
|
301
|
+
secrets.set(rtKey, req(await password({ message: "Microsoft refresh token" })));
|
|
302
|
+
}
|
|
303
|
+
auth = { type: "oauth2", provider: "microsoft", tenantId, clientId, clientSecretEnv: csKey, flow, refreshTokenEnv: rtKey };
|
|
304
|
+
}
|
|
305
|
+
else {
|
|
306
|
+
auth = { type: "oauth2", provider: "microsoft", tenantId, clientId, clientSecretEnv: csKey, flow };
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
else {
|
|
310
|
+
const preset = id in PRESETS ? PRESETS[id] : PRESETS.agh;
|
|
311
|
+
imapHost = req(await text({ message: "IMAP host", placeholder: preset.imap[0], defaultValue: preset.imap[0] })).trim();
|
|
312
|
+
imapPort = Number(req(await text({ message: "IMAP port", placeholder: String(preset.imap[1]), defaultValue: String(preset.imap[1]) })));
|
|
313
|
+
smtpHost = req(await text({ message: "SMTP host", placeholder: preset.smtp[0], defaultValue: preset.smtp[0] })).trim();
|
|
314
|
+
smtpPort = Number(req(await text({ message: "SMTP port", placeholder: String(preset.smtp[1]), defaultValue: String(preset.smtp[1]) })));
|
|
315
|
+
smtpSecure = smtpPort === 465;
|
|
316
|
+
const pKey = envKey(id, "PASSWORD");
|
|
317
|
+
secrets.set(pKey, req(await password({ message: "haslo / app-password" })));
|
|
318
|
+
auth = { type: "password", passwordEnv: pKey };
|
|
319
|
+
}
|
|
320
|
+
return {
|
|
321
|
+
account: {
|
|
322
|
+
id,
|
|
323
|
+
label,
|
|
324
|
+
email,
|
|
325
|
+
imap: { host: imapHost, port: imapPort, secure: imapPort === 993 },
|
|
326
|
+
smtp: { host: smtpHost, port: smtpPort, secure: smtpSecure },
|
|
327
|
+
auth,
|
|
328
|
+
},
|
|
329
|
+
secrets,
|
|
330
|
+
};
|
|
331
|
+
}
|
|
332
|
+
export async function runSetup() {
|
|
333
|
+
banner();
|
|
334
|
+
intro("poczta-mcp · konfigurator");
|
|
335
|
+
loadEnv(); // existing .env -> process.env, so 'Test polaczen' works on already-configured accounts
|
|
336
|
+
const secrets = new Map();
|
|
337
|
+
const existing = loadExistingConfig();
|
|
338
|
+
// --- tryb edycji istniejacej konfiguracji ---
|
|
339
|
+
if (existing) {
|
|
340
|
+
const cfg = existing;
|
|
341
|
+
note(summary(cfg), "Wykryto config.json");
|
|
342
|
+
let changed = false;
|
|
343
|
+
while (true) {
|
|
344
|
+
const action = req(await select({
|
|
345
|
+
message: "Co zrobic?",
|
|
346
|
+
options: [
|
|
347
|
+
{ value: "add", label: "Dodaj konto" },
|
|
348
|
+
...(cfg.accounts.length ? [{ value: "remove", label: "Usun konto" }] : []),
|
|
349
|
+
{ value: "channels", label: "Zmien kanaly podsumowania" },
|
|
350
|
+
{ value: "test", label: "Test polaczen" },
|
|
351
|
+
{ value: "save", label: "Zapisz i wyjdz" },
|
|
352
|
+
{ value: "quit", label: "Wyjscie bez zapisu" },
|
|
353
|
+
],
|
|
354
|
+
}));
|
|
355
|
+
if (action === "add") {
|
|
356
|
+
const taken = new Set(cfg.accounts.map((a) => a.id));
|
|
357
|
+
const { account, secrets: accS } = await addAccount(taken);
|
|
358
|
+
cfg.accounts.push(account);
|
|
359
|
+
for (const [k, v] of accS) {
|
|
360
|
+
secrets.set(k, v);
|
|
361
|
+
process.env[k] = v;
|
|
362
|
+
}
|
|
363
|
+
changed = true;
|
|
364
|
+
log.success(`dodano '${account.id}'`);
|
|
365
|
+
note(summary(cfg), "Po zmianie");
|
|
366
|
+
}
|
|
367
|
+
else if (action === "remove") {
|
|
368
|
+
const idr = req(await select({
|
|
369
|
+
message: "Ktore konto usunac?",
|
|
370
|
+
options: cfg.accounts.map((a) => ({ value: a.id, label: `${a.id} (${a.email})` })),
|
|
371
|
+
}));
|
|
372
|
+
cfg.accounts = cfg.accounts.filter((a) => a.id !== idr);
|
|
373
|
+
const before = cfg.digest.channels.length;
|
|
374
|
+
cfg.digest.channels = cfg.digest.channels.filter((c) => !(c.type === "email" && c.fromAccount === idr));
|
|
375
|
+
if (cfg.digest.channels.length !== before)
|
|
376
|
+
log.warn(`usunieto kanaly email uzywajace '${idr}'`);
|
|
377
|
+
if (!cfg.digest.channels.length)
|
|
378
|
+
cfg.digest.channels = [{ type: "chat" }];
|
|
379
|
+
changed = true;
|
|
380
|
+
log.success(`usunieto '${idr}'`);
|
|
381
|
+
note(summary(cfg), "Po zmianie");
|
|
382
|
+
}
|
|
383
|
+
else if (action === "channels") {
|
|
384
|
+
if (!cfg.accounts.length) {
|
|
385
|
+
log.warn("najpierw dodaj konto");
|
|
386
|
+
continue;
|
|
387
|
+
}
|
|
388
|
+
cfg.digest.channels = await configureChannels(cfg.accounts, secrets);
|
|
389
|
+
changed = true;
|
|
390
|
+
note(summary(cfg), "Po zmianie");
|
|
391
|
+
}
|
|
392
|
+
else if (action === "test") {
|
|
393
|
+
const parsed = configSchema.safeParse(cfg);
|
|
394
|
+
if (!parsed.success) {
|
|
395
|
+
log.error("config niepoprawny, napraw przed testem");
|
|
396
|
+
continue;
|
|
397
|
+
}
|
|
398
|
+
await runTest(parsed.data);
|
|
399
|
+
}
|
|
400
|
+
else if (action === "save") {
|
|
401
|
+
if (!cfg.accounts.length) {
|
|
402
|
+
log.error("brak kont, nie zapisuje");
|
|
403
|
+
continue;
|
|
404
|
+
}
|
|
405
|
+
const { cfgPath, envP } = writeAll(cfg, secrets);
|
|
406
|
+
note(`${cfgPath}\n${envP}`, "Zapisano");
|
|
407
|
+
changed = false;
|
|
408
|
+
break;
|
|
409
|
+
}
|
|
410
|
+
else {
|
|
411
|
+
if (changed && !req(await confirm({ message: "Sa niezapisane zmiany. Wyjsc bez zapisu?", initialValue: false }))) {
|
|
412
|
+
continue;
|
|
413
|
+
}
|
|
414
|
+
cancel("Wyjscie bez zapisu.");
|
|
415
|
+
return;
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
outro("Gotowe.");
|
|
419
|
+
return;
|
|
420
|
+
}
|
|
421
|
+
// --- nowa konfiguracja od zera ---
|
|
422
|
+
const accounts = [];
|
|
423
|
+
const takenIds = new Set();
|
|
424
|
+
do {
|
|
425
|
+
const { account, secrets: accS } = await addAccount(takenIds);
|
|
426
|
+
accounts.push(account);
|
|
427
|
+
takenIds.add(account.id);
|
|
428
|
+
for (const [k, v] of accS) {
|
|
429
|
+
secrets.set(k, v);
|
|
430
|
+
process.env[k] = v;
|
|
431
|
+
}
|
|
432
|
+
log.success(`dodano konto '${account.id}' (${account.email})`);
|
|
433
|
+
} while (req(await confirm({ message: "Dodac kolejne konto?", initialValue: false })));
|
|
434
|
+
const channels = await configureChannels(accounts, secrets);
|
|
435
|
+
const timezone = req(await text({ message: "Strefa czasowa digestu", placeholder: "Europe/Warsaw", defaultValue: "Europe/Warsaw" }));
|
|
436
|
+
const cfg = { accounts, digest: { channels, timezone } };
|
|
437
|
+
const { cfgPath, envP } = writeAll(cfg, secrets);
|
|
438
|
+
note(`${cfgPath}\n${envP}`, "Zapisano");
|
|
439
|
+
if (req(await confirm({ message: "Przetestowac polaczenia teraz?", initialValue: true }))) {
|
|
440
|
+
await runTest(cfg);
|
|
441
|
+
}
|
|
442
|
+
outro("Gotowe. Dalej: README -> sekcja 'Codzienny automat'.");
|
|
443
|
+
}
|
|
444
|
+
//# sourceMappingURL=setup.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"setup.js","sourceRoot":"","sources":["../src/setup.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAClE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EACL,KAAK,EACL,KAAK,EACL,IAAI,EACJ,QAAQ,EACR,MAAM,EACN,WAAW,EACX,OAAO,EACP,QAAQ,EACR,MAAM,EACN,IAAI,EACJ,OAAO,EACP,GAAG,GACJ,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,YAAY,EAAE,OAAO,EAAe,MAAM,aAAa,CAAC;AACjE,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAI/D,uCAAuC;AACvC,MAAM,MAAM,GAAG,kBAAkB,CAAC;AAClC,MAAM,KAAK,GAAG,SAAS,CAAC;AACxB,MAAM,WAAW,GAAG;IAClB,gCAAgC;IAChC,gCAAgC;IAChC,gCAAgC;IAChC,gCAAgC;IAChC,gCAAgC;IAChC,gCAAgC;CACjC,CAAC;AACF,MAAM,UAAU,GAAG;IACjB,6BAA6B;IAC7B,6BAA6B;IAC7B,6BAA6B;IAC7B,6BAA6B;IAC7B,6BAA6B;IAC7B,6BAA6B;CAC9B,CAAC;AAEF,SAAS,MAAM;IACb,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC3B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,WAAW,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAC5C,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,MAAM,GAAG,WAAW,CAAC,CAAC,CAAC,KAAK,UAAU,CAAC,CAAC,CAAC,GAAG,KAAK,IAAI,CAAC,CAAC;IACjF,CAAC;IACD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;AAC7B,CAAC;AAED,4FAA4F;AAC5F,SAAS,kBAAkB;IACzB,MAAM,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,aAAa,CAAC,CAAC;IAChD,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC;QAAE,OAAO,IAAI,CAAC;IAChC,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,YAAY,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC;QAC3E,OAAO,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;IAC7C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,SAAS,OAAO,CAAC,GAAW;IAC1B,MAAM,IAAI,GACR,GAAG,CAAC,QAAQ;SACT,GAAG,CACF,CAAC,CAAC,EAAE,EAAE,CACJ,KAAK,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,KAAK,KAAK,CAAC,CAAC,IAAI,CAAC,IAAI,KAAK,UAAU,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,SAAS,GAAG,CAAC,CAAC,IAAI,CAAC,QAAQ,GAAG,CACtG;SACA,IAAI,CAAC,IAAI,CAAC,IAAI,QAAQ,CAAC;IAC5B,MAAM,GAAG,GACP,GAAG,CAAC,MAAM,CAAC,QAAQ;SAChB,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CACT,CAAC,CAAC,IAAI,KAAK,OAAO;QAChB,CAAC,CAAC,cAAc,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,WAAW,GAAG;QAC3C,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,MAAM;YACjB,CAAC,CAAC,aAAa,CAAC,CAAC,IAAI,EAAE;YACvB,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,SAAS;gBACpB,CAAC,CAAC,cAAc,CAAC,CAAC,MAAM,GAAG;gBAC3B,CAAC,CAAC,QAAQ,CACjB;SACA,IAAI,CAAC,IAAI,CAAC,IAAI,QAAQ,CAAC;IAC5B,OAAO,WAAW,IAAI,6BAA6B,GAAG,EAAE,CAAC;AAC3D,CAAC;AAED,6EAA6E;AAC7E,KAAK,UAAU,iBAAiB,CAC9B,QAA4B,EAC5B,OAA4B;IAE5B,MAAM,MAAM,GAAG,GAAG,CAChB,MAAM,WAAW,CAAC;QAChB,OAAO,EAAE,uCAAuC;QAChD,OAAO,EAAE;YACP,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,sBAAsB,EAAE,IAAI,EAAE,UAAU,EAAE;YAClE,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,eAAe,EAAE;YACzC,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,sBAAsB,EAAE;YACjD,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,uBAAuB,EAAE;SACrD;QACD,aAAa,EAAE,CAAC,MAAM,CAAC;QACvB,QAAQ,EAAE,KAAK;KAChB,CAAC,CACS,CAAC;IAEd,MAAM,QAAQ,GAAa,EAAE,CAAC;IAC9B,IAAI,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;QAAE,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;IACpF,IAAI,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;QAC5B,MAAM,IAAI,GAAG,GAAG,CACd,MAAM,IAAI,CAAC;YACT,OAAO,EAAE,oCAAoC;YAC7C,WAAW,EAAE,2BAA2B;YACxC,YAAY,EAAE,2BAA2B;SAC1C,CAAC,CACH,CAAC;QACF,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;IACxC,CAAC;IACD,IAAI,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;QAC7B,MAAM,EAAE,GAAG,GAAG,CAAC,MAAM,IAAI,CAAC,EAAE,OAAO,EAAE,wBAAwB,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QACzE,MAAM,WAAW,GAAG,GAAG,CACrB,MAAM,MAAM,CAAC;YACX,OAAO,EAAE,uBAAuB;YAChC,OAAO,EAAE,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,EAAE,EAAE,KAAK,EAAE,GAAG,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,KAAK,GAAG,EAAE,CAAC,CAAC;SAC1F,CAAC,CACO,CAAC;QACZ,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,EAAE,WAAW,EAAE,OAAO,EAAE,kCAAkC,EAAE,CAAC,CAAC;IACjG,CAAC;IACD,IAAI,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC;QAC/B,MAAM,MAAM,GAAG,oBAAoB,CAAC;QACpC,MAAM,GAAG,GAAG,GAAG,CAAC,MAAM,QAAQ,CAAC,EAAE,OAAO,EAAE,cAAc,EAAE,CAAC,CAAC,CAAC;QAC7D,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;QACzB,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,GAAG,CAAC;QAC1B,MAAM,MAAM,GAAG,GAAG,CAChB,MAAM,MAAM,CAAC;YACX,OAAO,EAAE,iBAAiB;YAC1B,OAAO,EAAE;gBACP,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,sBAAsB,EAAE;gBACjD,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,4BAA4B,EAAE;aACtD;SACF,CAAC,CACgB,CAAC;QACrB,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IAC7D,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,2FAA2F;AAC3F,SAAS,QAAQ,CAAC,GAAW,EAAE,OAA4B;IACzD,MAAM,MAAM,GAAG,YAAY,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;IAC3C,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;QACpB,MAAM,CAAC,uBAAuB,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;QAC/E,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IACD,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,aAAa,CAAC,CAAC;IACtD,MAAM,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,MAAM,CAAC,CAAC;IAC5C,aAAa,CAAC,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,EAAE,MAAM,CAAC,CAAC;IAC5E,IAAI,UAAU,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IACpE,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,OAAO;QAAE,UAAU,GAAG,SAAS,CAAC,UAAU,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;IACvE,aAAa,CAAC,IAAI,EAAE,UAAU,EAAE,MAAM,CAAC,CAAC;IACxC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;AAC3B,CAAC;AAED,gGAAgG;AAChG,KAAK,UAAU,OAAO,CAAC,GAAW;IAChC,MAAM,EAAE,WAAW,EAAE,GAAG,MAAM,MAAM,CAAC,gBAAgB,CAAC,CAAC;IACvD,KAAK,MAAM,GAAG,IAAI,GAAG,CAAC,QAAQ,EAAE,CAAC;QAC/B,MAAM,CAAC,GAAG,OAAO,EAAE,CAAC;QACpB,CAAC,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC,EAAE,KAAK,GAAG,CAAC,KAAK,GAAG,CAAC,CAAC;QACpC,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,MAAM,WAAW,CAAC,GAAG,CAAC,CAAC;YACvC,CAAC,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,MAAM,OAAO,CAAC,MAAM,WAAW,CAAC,CAAC;QACtD,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,CAAC,CAAC,IAAI,CAAC,QAAQ,GAAG,CAAC,EAAE,MAAO,CAAW,CAAC,OAAO,EAAE,CAAC,CAAC;QACrD,CAAC;IACH,CAAC;AACH,CAAC;AAED;;;;;;GAMG;AAEH,MAAM,OAAO,GAAgF;IAC3F,GAAG,EAAE,EAAE,IAAI,EAAE,CAAC,mBAAmB,EAAE,GAAG,CAAC,EAAE,IAAI,EAAE,CAAC,mBAAmB,EAAE,GAAG,EAAE,IAAI,CAAC,EAAE;IACjF,KAAK,EAAE,EAAE,IAAI,EAAE,CAAC,gBAAgB,EAAE,GAAG,CAAC,EAAE,IAAI,EAAE,CAAC,gBAAgB,EAAE,GAAG,EAAE,IAAI,CAAC,EAAE;IAC7E,IAAI,EAAE,EAAE,IAAI,EAAE,CAAC,uBAAuB,EAAE,GAAG,CAAC,EAAE,IAAI,EAAE,CAAC,oBAAoB,EAAE,GAAG,EAAE,KAAK,CAAC,EAAE;CACzF,CAAC;AAEF,sEAAsE;AACtE,SAAS,GAAG,CAAI,KAAiB;IAC/B,IAAI,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;QACpB,MAAM,CAAC,8BAA8B,CAAC,CAAC;QACvC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IACD,OAAO,KAAU,CAAC;AACpB,CAAC;AAED,SAAS,MAAM,CAAC,EAAU,EAAE,MAAc;IACxC,OAAO,GAAG,EAAE,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,YAAY,EAAE,GAAG,CAAC,IAAI,MAAM,EAAE,CAAC;AACpE,CAAC;AAED,SAAS,SAAS,CAAC,OAAe,EAAE,GAAW,EAAE,KAAa;IAC5D,MAAM,IAAI,GAAG,GAAG,GAAG,IAAI,KAAK,EAAE,CAAC;IAC/B,MAAM,EAAE,GAAG,IAAI,MAAM,CAAC,IAAI,GAAG,MAAM,EAAE,GAAG,CAAC,CAAC;IAC1C,IAAI,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC;QAAE,OAAO,OAAO,CAAC,OAAO,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;IACvD,OAAO,OAAO,CAAC,OAAO,CAAC,MAAM,EAAE,IAAI,CAAC,GAAG,IAAI,GAAG,IAAI,CAAC;AACrD,CAAC;AAID,KAAK,UAAU,UAAU,CAAC,QAAqB;IAI7C,MAAM,OAAO,GAAG,IAAI,GAAG,EAAkB,CAAC;IAE1C,MAAM,EAAE,GAAG,GAAG,CACZ,MAAM,IAAI,CAAC;QACT,OAAO,EAAE,8DAA8D;QACvE,WAAW,EAAE,qBAAqB;QAClC,QAAQ,EAAE,CAAC,CAAC,EAAE,EAAE;YACd,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;YACzC,IAAI,CAAC,CAAC;gBAAE,OAAO,UAAU,CAAC;YAC1B,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC,CAAC;gBAAE,OAAO,iCAAiC,CAAC;YACvE,IAAI,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC;gBAAE,OAAO,cAAc,CAAC;YAC3C,OAAO,SAAS,CAAC;QACnB,CAAC;KACF,CAAC,CACH,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAEvB,MAAM,KAAK,GAAG,GAAG,CACf,MAAM,IAAI,CAAC;QACT,OAAO,EAAE,kDAAkD;QAC3D,WAAW,EAAE,EAAE;QACf,YAAY,EAAE,EAAE;KACjB,CAAC,CACH,CAAC;IAEF,MAAM,KAAK,GAAG,GAAG,CACf,MAAM,IAAI,CAAC;QACT,OAAO,EAAE,aAAa;QACtB,QAAQ,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,4BAA4B,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,mBAAmB,CAAC;KACzG,CAAC,CACH,CAAC,IAAI,EAAE,CAAC;IAET,MAAM,QAAQ,GAAG,GAAG,CAClB,MAAM,MAAM,CAAC;QACX,OAAO,EAAE,0BAA0B;QACnC,OAAO,EAAE;YACP,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,6BAA6B,EAAE,IAAI,EAAE,mBAAmB,EAAE;YACrF,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE;YAClD,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,yBAAyB,EAAE,IAAI,EAAE,QAAQ,EAAE;SACpE;KACF,CAAC,CACH,CAAC;IAEF,IAAI,QAAgB,EAAE,QAAgB,EAAE,QAAgB,EAAE,QAAgB,EAAE,UAAmB,CAAC;IAChG,IAAI,IAAiB,CAAC;IAEtB,IAAI,QAAQ,KAAK,OAAO,EAAE,CAAC;QACzB,CAAC,QAAQ,EAAE,QAAQ,CAAC,GAAG,OAAO,CAAC,KAAM,CAAC,IAAI,CAAC;QAC3C,CAAC,QAAQ,EAAE,QAAQ,EAAE,UAAU,CAAC,GAAG,OAAO,CAAC,KAAM,CAAC,IAAI,CAAC;QAEvD,MAAM,MAAM,GAAG,GAAG,CAChB,MAAM,MAAM,CAAC;YACX,OAAO,EAAE,wBAAwB;YACjC,OAAO,EAAE;gBACP,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,4BAA4B,EAAE,IAAI,EAAE,sCAAsC,EAAE;gBACnG,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,gCAAgC,EAAE;aAC5E;YACD,YAAY,EAAE,KAAK;SACpB,CAAC,CACgB,CAAC;QAErB,IAAI,MAAM,KAAK,KAAK,EAAE,CAAC;YACrB,IAAI,CACF,4EAA4E;gBAC1E,8EAA8E;gBAC9E,mEAAmE;gBACnE,+DAA+D,EACjE,oBAAoB,CACrB,CAAC;YACF,MAAM,IAAI,GAAG,MAAM,CAAC,EAAE,EAAE,UAAU,CAAC,CAAC;YACpC,OAAO,CAAC,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,MAAM,QAAQ,CAAC,EAAE,OAAO,EAAE,gCAAgC,EAAE,CAAC,CAAC,CAAC,CAAC;YACtF,IAAI,GAAG,EAAE,IAAI,EAAE,UAAU,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC;YAC/C,OAAO;gBACL,OAAO,EAAE;oBACP,EAAE;oBACF,KAAK;oBACL,KAAK;oBACL,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,KAAK,GAAG,EAAE;oBAClE,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE;oBAC5D,IAAI;iBACL;gBACD,OAAO;aACR,CAAC;QACJ,CAAC;QAED,IAAI,CACF,0CAA0C;YACxC,yFAAyF;YACzF,oEAAoE;YACpE,iFAAiF;YACjF,iEAAiE,EACnE,6BAA6B,CAC9B,CAAC;QACF,MAAM,QAAQ,GAAG,GAAG,CAClB,MAAM,IAAI,CAAC,EAAE,OAAO,EAAE,kBAAkB,EAAE,WAAW,EAAE,qCAAqC,EAAE,CAAC,CAChG,CAAC,IAAI,EAAE,CAAC;QACT,MAAM,KAAK,GAAG,MAAM,CAAC,EAAE,EAAE,eAAe,CAAC,CAAC;QAC1C,MAAM,KAAK,GAAG,MAAM,CAAC,EAAE,EAAE,eAAe,CAAC,CAAC;QAC1C,MAAM,YAAY,GAAG,GAAG,CAAC,MAAM,QAAQ,CAAC,EAAE,OAAO,EAAE,sBAAsB,EAAE,CAAC,CAAC,CAAC;QAC9E,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,YAAY,CAAC,CAAC;QAEjC,MAAM,IAAI,GAAG,GAAG,CACd,MAAM,OAAO,CAAC,EAAE,OAAO,EAAE,oDAAoD,EAAE,YAAY,EAAE,IAAI,EAAE,CAAC,CACrG,CAAC;QACF,IAAI,IAAI,EAAE,CAAC;YACT,MAAM,CAAC,GAAG,OAAO,EAAE,CAAC;YACpB,CAAC,CAAC,KAAK,CAAC,mCAAmC,CAAC,CAAC;YAC7C,IAAI,CAAC;gBACH,MAAM,EAAE,YAAY,EAAE,GAAG,MAAM,cAAc,CAAC,EAAE,QAAQ,EAAE,YAAY,EAAE,CAAC,CAAC;gBAC1E,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,YAAY,CAAC,CAAC;gBACjC,CAAC,CAAC,IAAI,CAAC,wBAAwB,CAAC,CAAC;YACnC,CAAC;YAAC,OAAO,CAAC,EAAE,CAAC;gBACX,CAAC,CAAC,IAAI,CAAC,iBAAiB,GAAI,CAAW,CAAC,OAAO,CAAC,CAAC;gBACjD,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC,MAAM,QAAQ,CAAC,EAAE,OAAO,EAAE,6BAA6B,EAAE,CAAC,CAAC,CAAC,CAAC;YACtF,CAAC;QACH,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC,MAAM,QAAQ,CAAC,EAAE,OAAO,EAAE,sBAAsB,EAAE,CAAC,CAAC,CAAC,CAAC;QAC/E,CAAC;QACD,IAAI,GAAG,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,eAAe,EAAE,KAAK,EAAE,eAAe,EAAE,KAAK,EAAE,CAAC;IAC1G,CAAC;SAAM,IAAI,QAAQ,KAAK,MAAM,EAAE,CAAC;QAC/B,CAAC,QAAQ,EAAE,QAAQ,CAAC,GAAG,OAAO,CAAC,IAAK,CAAC,IAAI,CAAC;QAC1C,CAAC,QAAQ,EAAE,QAAQ,EAAE,UAAU,CAAC,GAAG,OAAO,CAAC,IAAK,CAAC,IAAI,CAAC;QACtD,IAAI,CACF,iEAAiE;YAC/D,sEAAsE;YACtE,0FAA0F,EAC5F,0BAA0B,CAC3B,CAAC;QACF,MAAM,QAAQ,GAAG,GAAG,CAAC,MAAM,IAAI,CAAC,EAAE,OAAO,EAAE,gBAAgB,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QACvE,MAAM,QAAQ,GAAG,GAAG,CAAC,MAAM,IAAI,CAAC,EAAE,OAAO,EAAE,oBAAoB,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QAC3E,MAAM,KAAK,GAAG,MAAM,CAAC,EAAE,EAAE,eAAe,CAAC,CAAC;QAC1C,MAAM,YAAY,GAAG,GAAG,CAAC,MAAM,QAAQ,CAAC,EAAE,OAAO,EAAE,qBAAqB,EAAE,CAAC,CAAC,CAAC;QAC7E,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,YAAY,CAAC,CAAC;QACjC,MAAM,IAAI,GAAG,GAAG,CACd,MAAM,MAAM,CAAC;YACX,OAAO,EAAE,aAAa;YACtB,OAAO,EAAE;gBACP,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,sBAAsB,EAAE,IAAI,EAAE,0BAA0B,EAAE;gBACrF,EAAE,KAAK,EAAE,oBAAoB,EAAE,KAAK,EAAE,+BAA+B,EAAE,IAAI,EAAE,kDAAkD,EAAE;aAClI;SACF,CAAC,CACiC,CAAC;QACtC,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;YACvB,MAAM,KAAK,GAAG,MAAM,CAAC,EAAE,EAAE,eAAe,CAAC,CAAC;YAC1C,IAAI,CACF,oIAAoI;gBAClI,qFAAqF,EACvF,oBAAoB,CACrB,CAAC;YACF,MAAM,IAAI,GAAG,GAAG,CACd,MAAM,OAAO,CAAC,EAAE,OAAO,EAAE,uDAAuD,EAAE,YAAY,EAAE,IAAI,EAAE,CAAC,CACxG,CAAC;YACF,IAAI,IAAI,EAAE,CAAC;gBACT,MAAM,CAAC,GAAG,OAAO,EAAE,CAAC;gBACpB,CAAC,CAAC,KAAK,CAAC,mCAAmC,CAAC,CAAC;gBAC7C,IAAI,CAAC;oBACH,MAAM,EAAE,YAAY,EAAE,GAAG,MAAM,iBAAiB,CAAC,EAAE,QAAQ,EAAE,QAAQ,EAAE,YAAY,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;oBACnG,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,YAAY,CAAC,CAAC;oBACjC,CAAC,CAAC,IAAI,CAAC,wBAAwB,CAAC,CAAC;gBACnC,CAAC;gBAAC,OAAO,CAAC,EAAE,CAAC;oBACX,CAAC,CAAC,IAAI,CAAC,iBAAiB,GAAI,CAAW,CAAC,OAAO,CAAC,CAAC;oBACjD,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC,MAAM,QAAQ,CAAC,EAAE,OAAO,EAAE,6BAA6B,EAAE,CAAC,CAAC,CAAC,CAAC;gBACtF,CAAC;YACH,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC,MAAM,QAAQ,CAAC,EAAE,OAAO,EAAE,yBAAyB,EAAE,CAAC,CAAC,CAAC,CAAC;YAClF,CAAC;YACD,IAAI,GAAG,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,WAAW,EAAE,QAAQ,EAAE,QAAQ,EAAE,eAAe,EAAE,KAAK,EAAE,IAAI,EAAE,eAAe,EAAE,KAAK,EAAE,CAAC;QAC7H,CAAC;aAAM,CAAC;YACN,IAAI,GAAG,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,WAAW,EAAE,QAAQ,EAAE,QAAQ,EAAE,eAAe,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;QACrG,CAAC;IACH,CAAC;SAAM,CAAC;QACN,MAAM,MAAM,GAAG,EAAE,IAAI,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAE,CAAC,CAAC,CAAC,OAAO,CAAC,GAAI,CAAC;QAC3D,QAAQ,GAAG,GAAG,CAAC,MAAM,IAAI,CAAC,EAAE,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,YAAY,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QACvH,QAAQ,GAAG,MAAM,CAAC,GAAG,CAAC,MAAM,IAAI,CAAC,EAAE,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,YAAY,EAAE,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QACxI,QAAQ,GAAG,GAAG,CAAC,MAAM,IAAI,CAAC,EAAE,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,YAAY,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QACvH,QAAQ,GAAG,MAAM,CAAC,GAAG,CAAC,MAAM,IAAI,CAAC,EAAE,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,YAAY,EAAE,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QACxI,UAAU,GAAG,QAAQ,KAAK,GAAG,CAAC;QAC9B,MAAM,IAAI,GAAG,MAAM,CAAC,EAAE,EAAE,UAAU,CAAC,CAAC;QACpC,OAAO,CAAC,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,MAAM,QAAQ,CAAC,EAAE,OAAO,EAAE,sBAAsB,EAAE,CAAC,CAAC,CAAC,CAAC;QAC5E,IAAI,GAAG,EAAE,IAAI,EAAE,UAAU,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC;IACjD,CAAC;IAED,OAAO;QACL,OAAO,EAAE;YACP,EAAE;YACF,KAAK;YACL,KAAK;YACL,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,KAAK,GAAG,EAAE;YAClE,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE;YAC5D,IAAI;SACL;QACD,OAAO;KACR,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,QAAQ;IAC5B,MAAM,EAAE,CAAC;IACT,KAAK,CAAC,2BAA2B,CAAC,CAAC;IACnC,OAAO,EAAE,CAAC,CAAC,wFAAwF;IAEnG,MAAM,OAAO,GAAG,IAAI,GAAG,EAAkB,CAAC;IAC1C,MAAM,QAAQ,GAAG,kBAAkB,EAAE,CAAC;IAEtC,+CAA+C;IAC/C,IAAI,QAAQ,EAAE,CAAC;QACb,MAAM,GAAG,GAAG,QAAQ,CAAC;QACrB,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,qBAAqB,CAAC,CAAC;QAC1C,IAAI,OAAO,GAAG,KAAK,CAAC;QAEpB,OAAO,IAAI,EAAE,CAAC;YACZ,MAAM,MAAM,GAAG,GAAG,CAChB,MAAM,MAAM,CAAC;gBACX,OAAO,EAAE,YAAY;gBACrB,OAAO,EAAE;oBACP,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,aAAa,EAAE;oBACtC,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,YAAY,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;oBAC1E,EAAE,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE,2BAA2B,EAAE;oBACzD,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,eAAe,EAAE;oBACzC,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,gBAAgB,EAAE;oBAC1C,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,oBAAoB,EAAE;iBAC/C;aACF,CAAC,CACO,CAAC;YAEZ,IAAI,MAAM,KAAK,KAAK,EAAE,CAAC;gBACrB,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;gBACrD,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,GAAG,MAAM,UAAU,CAAC,KAAK,CAAC,CAAC;gBAC3D,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;gBAC3B,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC;oBAC1B,OAAO,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;oBAClB,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;gBACrB,CAAC;gBACD,OAAO,GAAG,IAAI,CAAC;gBACf,GAAG,CAAC,OAAO,CAAC,WAAW,OAAO,CAAC,EAAE,GAAG,CAAC,CAAC;gBACtC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,YAAY,CAAC,CAAC;YACnC,CAAC;iBAAM,IAAI,MAAM,KAAK,QAAQ,EAAE,CAAC;gBAC/B,MAAM,GAAG,GAAG,GAAG,CACb,MAAM,MAAM,CAAC;oBACX,OAAO,EAAE,qBAAqB;oBAC9B,OAAO,EAAE,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,EAAE,EAAE,KAAK,EAAE,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,KAAK,GAAG,EAAE,CAAC,CAAC;iBACnF,CAAC,CACO,CAAC;gBACZ,GAAG,CAAC,QAAQ,GAAG,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,GAAG,CAAC,CAAC;gBACxD,MAAM,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC;gBAC1C,GAAG,CAAC,MAAM,CAAC,QAAQ,GAAG,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAC9C,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,OAAO,IAAI,CAAC,CAAC,WAAW,KAAK,GAAG,CAAC,CACtD,CAAC;gBACF,IAAI,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,KAAK,MAAM;oBAAE,GAAG,CAAC,IAAI,CAAC,oCAAoC,GAAG,GAAG,CAAC,CAAC;gBAChG,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM;oBAAE,GAAG,CAAC,MAAM,CAAC,QAAQ,GAAG,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;gBAC1E,OAAO,GAAG,IAAI,CAAC;gBACf,GAAG,CAAC,OAAO,CAAC,aAAa,GAAG,GAAG,CAAC,CAAC;gBACjC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,YAAY,CAAC,CAAC;YACnC,CAAC;iBAAM,IAAI,MAAM,KAAK,UAAU,EAAE,CAAC;gBACjC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC;oBACzB,GAAG,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAC;oBACjC,SAAS;gBACX,CAAC;gBACD,GAAG,CAAC,MAAM,CAAC,QAAQ,GAAG,MAAM,iBAAiB,CAAC,GAAG,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;gBACrE,OAAO,GAAG,IAAI,CAAC;gBACf,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,YAAY,CAAC,CAAC;YACnC,CAAC;iBAAM,IAAI,MAAM,KAAK,MAAM,EAAE,CAAC;gBAC7B,MAAM,MAAM,GAAG,YAAY,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;gBAC3C,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;oBACpB,GAAG,CAAC,KAAK,CAAC,yCAAyC,CAAC,CAAC;oBACrD,SAAS;gBACX,CAAC;gBACD,MAAM,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;YAC7B,CAAC;iBAAM,IAAI,MAAM,KAAK,MAAM,EAAE,CAAC;gBAC7B,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC;oBACzB,GAAG,CAAC,KAAK,CAAC,yBAAyB,CAAC,CAAC;oBACrC,SAAS;gBACX,CAAC;gBACD,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,GAAG,QAAQ,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;gBACjD,IAAI,CAAC,GAAG,OAAO,KAAK,IAAI,EAAE,EAAE,UAAU,CAAC,CAAC;gBACxC,OAAO,GAAG,KAAK,CAAC;gBAChB,MAAM;YACR,CAAC;iBAAM,CAAC;gBACN,IAAI,OAAO,IAAI,CAAC,GAAG,CAAC,MAAM,OAAO,CAAC,EAAE,OAAO,EAAE,0CAA0C,EAAE,YAAY,EAAE,KAAK,EAAE,CAAC,CAAC,EAAE,CAAC;oBACjH,SAAS;gBACX,CAAC;gBACD,MAAM,CAAC,qBAAqB,CAAC,CAAC;gBAC9B,OAAO;YACT,CAAC;QACH,CAAC;QAED,KAAK,CAAC,SAAS,CAAC,CAAC;QACjB,OAAO;IACT,CAAC;IAED,oCAAoC;IACpC,MAAM,QAAQ,GAAuB,EAAE,CAAC;IACxC,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAU,CAAC;IACnC,GAAG,CAAC;QACF,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,GAAG,MAAM,UAAU,CAAC,QAAQ,CAAC,CAAC;QAC9D,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACvB,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;QACzB,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC;YAC1B,OAAO,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;YAClB,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;QACrB,CAAC;QACD,GAAG,CAAC,OAAO,CAAC,iBAAiB,OAAO,CAAC,EAAE,MAAM,OAAO,CAAC,KAAK,GAAG,CAAC,CAAC;IACjE,CAAC,QAAQ,GAAG,CAAC,MAAM,OAAO,CAAC,EAAE,OAAO,EAAE,sBAAsB,EAAE,YAAY,EAAE,KAAK,EAAE,CAAC,CAAC,EAAE;IAEvF,MAAM,QAAQ,GAAG,MAAM,iBAAiB,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IAC5D,MAAM,QAAQ,GAAG,GAAG,CAClB,MAAM,IAAI,CAAC,EAAE,OAAO,EAAE,wBAAwB,EAAE,WAAW,EAAE,eAAe,EAAE,YAAY,EAAE,eAAe,EAAE,CAAC,CAC/G,CAAC;IAEF,MAAM,GAAG,GAAW,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,QAAQ,EAAE,QAAQ,EAAE,EAAE,CAAC;IACjE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,GAAG,QAAQ,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;IACjD,IAAI,CAAC,GAAG,OAAO,KAAK,IAAI,EAAE,EAAE,UAAU,CAAC,CAAC;IAExC,IAAI,GAAG,CAAC,MAAM,OAAO,CAAC,EAAE,OAAO,EAAE,gCAAgC,EAAE,YAAY,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC;QAC1F,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC;IACrB,CAAC;IAED,KAAK,CAAC,sDAAsD,CAAC,CAAC;AAChE,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@prbartosh/poczta-mcp",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "MCP server for multiple email accounts (IMAP/SMTP, password + Google/Microsoft OAuth2). Daily unread-triage digest.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"author": "prbartosh",
|
|
7
|
+
"license": "MIT",
|
|
8
|
+
"keywords": [
|
|
9
|
+
"mcp",
|
|
10
|
+
"model-context-protocol",
|
|
11
|
+
"email",
|
|
12
|
+
"imap",
|
|
13
|
+
"smtp",
|
|
14
|
+
"claude",
|
|
15
|
+
"oauth2"
|
|
16
|
+
],
|
|
17
|
+
"repository": {
|
|
18
|
+
"type": "git",
|
|
19
|
+
"url": "git+https://github.com/prbartosh/poczta-mcp.git"
|
|
20
|
+
},
|
|
21
|
+
"homepage": "https://github.com/prbartosh/poczta-mcp#readme",
|
|
22
|
+
"publishConfig": {
|
|
23
|
+
"access": "public"
|
|
24
|
+
},
|
|
25
|
+
"bin": {
|
|
26
|
+
"poczta-mcp": "dist/index.js"
|
|
27
|
+
},
|
|
28
|
+
"files": [
|
|
29
|
+
"dist",
|
|
30
|
+
"skills",
|
|
31
|
+
"config.example.json",
|
|
32
|
+
".env.example",
|
|
33
|
+
"cron.example",
|
|
34
|
+
"README.md"
|
|
35
|
+
],
|
|
36
|
+
"engines": {
|
|
37
|
+
"node": ">=20.12"
|
|
38
|
+
},
|
|
39
|
+
"scripts": {
|
|
40
|
+
"build": "tsc",
|
|
41
|
+
"dev": "tsc --watch",
|
|
42
|
+
"start": "node dist/index.js",
|
|
43
|
+
"setup": "node dist/index.js setup",
|
|
44
|
+
"digest": "node dist/index.js digest",
|
|
45
|
+
"prepublishOnly": "npm run build"
|
|
46
|
+
},
|
|
47
|
+
"dependencies": {
|
|
48
|
+
"@clack/prompts": "^1.6.0",
|
|
49
|
+
"@modelcontextprotocol/sdk": "^1.12.0",
|
|
50
|
+
"html-to-text": "^9.0.5",
|
|
51
|
+
"imapflow": "^1.0.171",
|
|
52
|
+
"mailparser": "^3.7.1",
|
|
53
|
+
"nodemailer": "^9.0.1",
|
|
54
|
+
"zod": "^3.24.1"
|
|
55
|
+
},
|
|
56
|
+
"devDependencies": {
|
|
57
|
+
"@types/mailparser": "^3.4.5",
|
|
58
|
+
"@types/node": "^22.10.0",
|
|
59
|
+
"@types/nodemailer": "^8.0.1",
|
|
60
|
+
"typescript": "^5.7.2"
|
|
61
|
+
}
|
|
62
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: daily-briefing
|
|
3
|
+
description: Codzienny przeglad nieprzeczytanej poczty ze wszystkich kont. Klasyfikuje maile (wazne / wymaga akcji / warto wiedziec / opcjonalne), buduje podsumowanie, dostarcza je kanalami z konfiguracji i oznacza jako przeczytane TYLKO maile niewymagajace akcji. Uruchamiana codziennie przez cron (claude -p) albo recznie.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Codzienny przeglad poczty
|
|
7
|
+
|
|
8
|
+
Cel: raz dziennie zebrac wszystko nieprzeczytane, powiedziec co wazne, zostawic unread to co wymaga uwagi, oznaczyc reszte jako przeczytane.
|
|
9
|
+
|
|
10
|
+
Uzywasz serwera MCP `poczta` (tooly `mcp__poczta__*`). Nie wysylasz zadnych maili (poza dostarczeniem podsumowania przez `deliver_digest`). NIGDY nie wolaj `send_email` w tym przeplywie.
|
|
11
|
+
|
|
12
|
+
## Kroki
|
|
13
|
+
|
|
14
|
+
1. `get_unread` BEZ argumentu `account` (obejmuje wszystkie konta). Domyslnie zwraca 35 najnowszych i nie starszych niz 3 dni (parametry `max_results`, `max_age_days`). Dostajesz liste: `account`, `uid`, `from`, `subject`, `date`, `preview`.
|
|
15
|
+
2. Jesli `preview` nie wystarcza by ocenic wage maila (np. wyglada na pismo od czlowieka z prosba), dla NAJWYZEJ kilku takich wywolaj `get_email_body` po `account`+`uid`. Nie pobieraj tresci masowo, oszczedzaj.
|
|
16
|
+
3. Sklasyfikuj kazdy mail do jednej z 4 kategorii (rubryka nizej).
|
|
17
|
+
4. Zbuduj podsumowanie w markdown (szablon nizej).
|
|
18
|
+
5. `deliver_digest` z tym markdownem (uzyje kanalow z konfiguracji).
|
|
19
|
+
6. Oznacz jako przeczytane TYLKO kategorie 🟡 i ⚪. Zostaw unread 🔴 i 🟠. Grupuj `uid` per `account` i wolaj `mark_as_read` raz na konto (batch).
|
|
20
|
+
|
|
21
|
+
## Rubryka klasyfikacji
|
|
22
|
+
|
|
23
|
+
- 🔴 **Wazne, przeczytaj** — istotna informacja od czlowieka/instytucji, decyzje, terminy, zmiany planu, dziekanat/HR/klient. Zostaje unread.
|
|
24
|
+
- 🟠 **Wymaga akcji** — trzeba cos zrobic: odpowiedziec, zaplacic, wgrac, potwierdzic, deadline na karku. Zostaje unread. Dopisz jaka akcja i do kiedy.
|
|
25
|
+
- 🟡 **Warto wiedziec** — newslettery wewnetrzne, ogloszenia, info bez akcji. Oznacz przeczytane.
|
|
26
|
+
- ⚪ **Opcjonalne / szum** — marketing, automaty (powiadomienia systemowe, "nie odpowiadaj"), promocje. Oznacz przeczytane.
|
|
27
|
+
|
|
28
|
+
Zasady oceny:
|
|
29
|
+
- Nadawcy typu `noreply@`, `no-reply@`, "Automatyczne powiadomienie", Coursera/marketing => zwykle ⚪.
|
|
30
|
+
- Powiadomienia bezpieczenstwa (nowy token, nowe logowanie, OAuth app added) => 🔴 jesli moga byc nieoczekiwane, inaczej 🟡.
|
|
31
|
+
- Maile od realnej osoby (imie.nazwisko@) z trescia => co najmniej 🔴, czesto 🟠.
|
|
32
|
+
- W razie watpliwosci klasyfikuj wyzej (lepiej zostawic unread niz ukryc wazne).
|
|
33
|
+
|
|
34
|
+
## Szablon podsumowania
|
|
35
|
+
|
|
36
|
+
```markdown
|
|
37
|
+
# Przeglad poczty — {DATA}
|
|
38
|
+
|
|
39
|
+
Nieprzeczytane: {N} ({lista kont z liczbami}).
|
|
40
|
+
|
|
41
|
+
## 🟠 Wymaga akcji ({k})
|
|
42
|
+
- **{temat}** — {nadawca} · {konto} · akcja: {co zrobic, do kiedy}
|
|
43
|
+
|
|
44
|
+
## 🔴 Wazne, przeczytaj ({k})
|
|
45
|
+
- **{temat}** — {nadawca} · {konto} · {jedno zdanie dlaczego}
|
|
46
|
+
|
|
47
|
+
## 🟡 Warto wiedziec ({k})
|
|
48
|
+
- {temat} — {nadawca} · {konto}
|
|
49
|
+
|
|
50
|
+
## ⚪ Opcjonalne ({k})
|
|
51
|
+
- {zwiezle, mozna zbiorczo: "12 newsletterow/marketing"}
|
|
52
|
+
|
|
53
|
+
---
|
|
54
|
+
Oznaczono jako przeczytane: {liczba} (🟡 + ⚪). Zostawiono unread: {liczba} (🔴 + 🟠).
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Pisz po polsku, rzeczowo, bez ozdobnikow. Sekcje akcji i wazne na gorze. Jesli brak nieprzeczytanych, krotki komunikat "brak nowych maili" i koniec (nic nie oznaczaj).
|