@thesashadev/girl-agent 0.1.4 → 0.1.5

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.
Files changed (3) hide show
  1. package/CHANGELOG.md +10 -0
  2. package/dist/cli.js +123 -23
  3. package/package.json +1 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,15 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.1.5 — owner TG credentials proxy
4
+
5
+ Дата: 2026-05-06
6
+
7
+ - Добавлен TG auth proxy для пользователей без доступа к my.telegram.org (виртуальные номера, новые аккаунты, VPN с IP датацентра).
8
+ - Новый шаг визарда: выбор между своими api_id/api_hash или использованием от владельца.
9
+ - Весь процесс авторизации через MTProto идёт через прокси-сервер — креды владельца не отображаются.
10
+ - Добавлен модуль `src/telegram/remote-auth.ts` — HTTP-клиент для прокси.
11
+ - Proxy URL настраивается через `GIRL_AGENT_AUTH_PROXY` env var (по умолчанию `https://tgproxy.girl-agent.com`).
12
+
3
13
  ## 0.1.4 — npm publish automation
4
14
 
5
15
  Дата: 2026-05-06
package/dist/cli.js CHANGED
@@ -1353,6 +1353,35 @@ function fallbackBusySchedule(name, age) {
1353
1353
  // src/wizard/index.tsx
1354
1354
  init_userbot();
1355
1355
 
1356
+ // src/telegram/remote-auth.ts
1357
+ init_esm_shims();
1358
+ var DEFAULT_PROXY = "https://tgproxy.girl-agent.com";
1359
+ function proxyUrl() {
1360
+ return process.env.GIRL_AGENT_AUTH_PROXY ?? DEFAULT_PROXY;
1361
+ }
1362
+ async function post(path5, body) {
1363
+ const res = await fetch(`${proxyUrl()}${path5}`, {
1364
+ method: "POST",
1365
+ headers: { "Content-Type": "application/json" },
1366
+ body: JSON.stringify(body)
1367
+ });
1368
+ const data = await res.json();
1369
+ if (!res.ok) throw new Error(data.error ?? `proxy ${path5} failed (${res.status})`);
1370
+ return data;
1371
+ }
1372
+ function remoteSendCode(phone) {
1373
+ return post("/send-code", { phone });
1374
+ }
1375
+ function remoteVerifyCode(loginToken, code) {
1376
+ return post("/verify-code", { loginToken, code });
1377
+ }
1378
+ function remoteVerifyPassword(loginToken, password) {
1379
+ return post("/verify-password", { loginToken, password });
1380
+ }
1381
+ function isNeeds2FA(r) {
1382
+ return "needs2fa" in r && r.needs2fa === true;
1383
+ }
1384
+
1356
1385
  // src/data/names.ts
1357
1386
  init_esm_shims();
1358
1387
  var NAMES_RU = [
@@ -1577,6 +1606,8 @@ function Wizard({ initial, onDone }) {
1577
1606
  const [code, setCode] = useState("");
1578
1607
  const [pass2fa, setPass2fa] = useState("");
1579
1608
  const [sessionString, setSessionString] = useState(initial?.telegram?.sessionString ?? "");
1609
+ const [useOwnerCreds, setUseOwnerCreds] = useState(false);
1610
+ const [loginToken, setLoginToken] = useState("");
1580
1611
  const [llmPresetId, setLlmPresetId] = useState(initial?.llm?.presetId ?? "openai");
1581
1612
  const [llmProto, setLlmProto] = useState(initial?.llm?.proto ?? "openai");
1582
1613
  const [llmBaseURL, setLlmBaseURL] = useState(initial?.llm?.baseURL ?? "");
@@ -1681,7 +1712,7 @@ function Wizard({ initial, onDone }) {
1681
1712
  onSelect: (it) => {
1682
1713
  const m = it.value;
1683
1714
  setMode(m);
1684
- setStep(m === "bot" ? "tg-bot-token" : "tg-userbot-api");
1715
+ setStep(m === "bot" ? "tg-bot-token" : "tg-userbot-source");
1685
1716
  }
1686
1717
  }
1687
1718
  )));
@@ -1696,39 +1727,108 @@ function Wizard({ initial, onDone }) {
1696
1727
  setStep("api-preset");
1697
1728
  } })), error && /* @__PURE__ */ React.createElement(Text, { color: "red" }, error));
1698
1729
  }
1730
+ if (step === "tg-userbot-source") {
1731
+ return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", padding: 1 }, /* @__PURE__ */ React.createElement(Header, { sub: "\u0443 \u0442\u0435\u0431\u044F \u0435\u0441\u0442\u044C \u0441\u0432\u043E\u0438 API credentials?" }), /* @__PURE__ */ React.createElement(Bar, { step: 1, total: 9 }), /* @__PURE__ */ React.createElement(Box, { marginTop: 1 }, /* @__PURE__ */ React.createElement(
1732
+ SelectInput,
1733
+ {
1734
+ items: [
1735
+ { label: "\u0414\u0430, \u0443 \u043C\u0435\u043D\u044F \u0435\u0441\u0442\u044C api_id \u0438 api_hash (my.telegram.org)", value: "own" },
1736
+ { label: "\u041D\u0435\u0442 \u2014 \u0438\u0441\u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u0442\u044C \u043E\u0442 \u0432\u043B\u0430\u0434\u0435\u043B\u044C\u0446\u0430 \u0431\u043E\u0442\u0430", value: "owner" }
1737
+ ],
1738
+ onSelect: (it) => {
1739
+ if (it.value === "own") {
1740
+ setUseOwnerCreds(false);
1741
+ setStep("tg-userbot-api");
1742
+ } else {
1743
+ setUseOwnerCreds(true);
1744
+ setStep("tg-userbot-phone");
1745
+ }
1746
+ }
1747
+ }
1748
+ )), /* @__PURE__ */ React.createElement(Box, { marginTop: 1 }, /* @__PURE__ */ React.createElement(Text, { dimColor: true }, "\u0435\u0441\u043B\u0438 \u043D\u0435 \u043C\u043E\u0436\u0435\u0448\u044C \u0441\u043E\u0437\u0434\u0430\u0442\u044C \u043F\u0440\u0438\u043B\u043E\u0436\u0435\u043D\u0438\u0435 \u043D\u0430 my.telegram.org \u2014 \u0432\u044B\u0431\u0435\u0440\u0438 \u0432\u0442\u043E\u0440\u043E\u0439 \u0432\u0430\u0440\u0438\u0430\u043D\u0442")));
1749
+ }
1699
1750
  if (step === "tg-userbot-api") {
1700
1751
  return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", padding: 1 }, /* @__PURE__ */ React.createElement(Header, { sub: "userbot \xB7 my.telegram.org \u2192 API_ID \u0438 API_HASH" }), /* @__PURE__ */ React.createElement(Bar, { step: 1, total: 9 }), focusedInput === "apiId" ? /* @__PURE__ */ React.createElement(Box, { marginTop: 1 }, /* @__PURE__ */ React.createElement(Text, null, "API_ID: "), /* @__PURE__ */ React.createElement(TextInput, { value: apiId, onChange: setApiId, onSubmit: () => setFocusedInput("apiHash") })) : /* @__PURE__ */ React.createElement(Box, { marginTop: 1 }, /* @__PURE__ */ React.createElement(Text, null, "API_ID: "), /* @__PURE__ */ React.createElement(Text, { color: focusedInput === "apiHash" ? "dimColor" : "white" }, apiId || "(\u043F\u0443\u0441\u0442\u043E)")), focusedInput === "apiHash" ? /* @__PURE__ */ React.createElement(Box, null, /* @__PURE__ */ React.createElement(Text, null, "API_HASH: "), /* @__PURE__ */ React.createElement(TextInput, { value: apiHash, onChange: setApiHash, mask: "\u2022", onSubmit: () => apiId && setStep("tg-userbot-phone") })) : /* @__PURE__ */ React.createElement(Box, null, /* @__PURE__ */ React.createElement(Text, null, "API_HASH: "), /* @__PURE__ */ React.createElement(Text, { color: focusedInput === "apiId" ? "dimColor" : "white" }, apiHash ? "\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022" : "(\u043F\u0443\u0441\u0442\u043E)")), /* @__PURE__ */ React.createElement(Box, { marginTop: 1 }, /* @__PURE__ */ React.createElement(Text, { dimColor: true }, "Tab / \u0441\u0442\u0440\u0435\u043B\u043A\u0438 \u0447\u0442\u043E\u0431\u044B \u043F\u0435\u0440\u0435\u043A\u043B\u044E\u0447\u0438\u0442\u044C\u0441\u044F \u043C\u0435\u0436\u0434\u0443 \u043F\u043E\u043B\u044F\u043C\u0438")));
1701
1752
  }
1702
1753
  if (step === "tg-userbot-phone") {
1703
1754
  return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", padding: 1 }, /* @__PURE__ */ React.createElement(Header, { sub: "\u0442\u0435\u043B\u0435\u0444\u043E\u043D \u0432 \u043C\u0435\u0436\u0434\u0443\u043D\u0430\u0440\u043E\u0434\u043D\u043E\u043C \u0444\u043E\u0440\u043C\u0430\u0442\u0435 (+7\u2026)" }), /* @__PURE__ */ React.createElement(Bar, { step: 1, total: 9 }), /* @__PURE__ */ React.createElement(Box, { marginTop: 1 }, /* @__PURE__ */ React.createElement(Text, null, "Phone: "), /* @__PURE__ */ React.createElement(TextInput, { value: phone, onChange: setPhone, onSubmit: async () => {
1704
- setStep("tg-userbot-code");
1705
- setGenStatus("\u043E\u0442\u043F\u0440\u0430\u0432\u043B\u044F\u0435\u043C \u043A\u043E\u0434\u2026");
1706
- try {
1707
- const sess = await userbotLogin({
1708
- apiId: Number(apiId),
1709
- apiHash,
1710
- phone,
1711
- promptCode: () => new Promise((res) => setCodeResolver(() => res)),
1712
- promptPassword: () => new Promise((res) => setPassResolver(() => res))
1713
- });
1714
- setSessionString(sess);
1715
- setStep("api-preset");
1716
- } catch (e) {
1717
- setError(e.message);
1718
- setStep("tg-userbot-phone");
1755
+ setError(null);
1756
+ if (useOwnerCreds) {
1757
+ setGenStatus("\u043E\u0442\u043F\u0440\u0430\u0432\u043B\u044F\u0435\u043C \u043A\u043E\u0434 \u0447\u0435\u0440\u0435\u0437 \u043F\u0440\u043E\u043A\u0441\u0438\u2026");
1758
+ setStep("tg-userbot-code");
1759
+ try {
1760
+ const result = await remoteSendCode(phone);
1761
+ setLoginToken(result.loginToken);
1762
+ } catch (e) {
1763
+ setError(e.message);
1764
+ setStep("tg-userbot-phone");
1765
+ }
1766
+ } else {
1767
+ setStep("tg-userbot-code");
1768
+ setGenStatus("\u043E\u0442\u043F\u0440\u0430\u0432\u043B\u044F\u0435\u043C \u043A\u043E\u0434\u2026");
1769
+ try {
1770
+ const sess = await userbotLogin({
1771
+ apiId: Number(apiId),
1772
+ apiHash,
1773
+ phone,
1774
+ promptCode: () => new Promise((res) => setCodeResolver(() => res)),
1775
+ promptPassword: () => new Promise((res) => setPassResolver(() => res))
1776
+ });
1777
+ setSessionString(sess);
1778
+ setStep("api-preset");
1779
+ } catch (e) {
1780
+ setError(e.message);
1781
+ setStep("tg-userbot-phone");
1782
+ }
1719
1783
  }
1720
1784
  } })), error && /* @__PURE__ */ React.createElement(Text, { color: "red" }, error));
1721
1785
  }
1722
1786
  if (step === "tg-userbot-code") {
1723
- return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", padding: 1 }, /* @__PURE__ */ React.createElement(Header, { sub: "\u043A\u043E\u0434 \u0438\u0437 Telegram" }), /* @__PURE__ */ React.createElement(Bar, { step: 1, total: 9 }), /* @__PURE__ */ React.createElement(Box, { marginTop: 1 }, /* @__PURE__ */ React.createElement(Text, null, "Code: "), /* @__PURE__ */ React.createElement(TextInput, { value: code, onChange: setCode, onSubmit: () => {
1724
- codeResolver?.(code);
1725
- setStep("tg-userbot-pass");
1726
- } })));
1787
+ return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", padding: 1 }, /* @__PURE__ */ React.createElement(Header, { sub: "\u043A\u043E\u0434 \u0438\u0437 Telegram" }), /* @__PURE__ */ React.createElement(Bar, { step: 1, total: 9 }), /* @__PURE__ */ React.createElement(Box, { marginTop: 1 }, /* @__PURE__ */ React.createElement(Text, null, "Code: "), /* @__PURE__ */ React.createElement(TextInput, { value: code, onChange: setCode, onSubmit: async () => {
1788
+ if (useOwnerCreds) {
1789
+ if (!loginToken) {
1790
+ setError("\u0435\u0449\u0451 \u043E\u0442\u043F\u0440\u0430\u0432\u043B\u044F\u0435\u043C \u043A\u043E\u0434, \u043F\u043E\u0434\u043E\u0436\u0434\u0438\u2026");
1791
+ return;
1792
+ }
1793
+ setError(null);
1794
+ try {
1795
+ const result = await remoteVerifyCode(loginToken, code);
1796
+ if (isNeeds2FA(result)) {
1797
+ setStep("tg-userbot-pass");
1798
+ } else {
1799
+ setApiId(String(result.apiId));
1800
+ setApiHash(result.apiHash);
1801
+ setSessionString(result.sessionString);
1802
+ setStep("api-preset");
1803
+ }
1804
+ } catch (e) {
1805
+ setError(e.message);
1806
+ setStep("tg-userbot-phone");
1807
+ }
1808
+ } else {
1809
+ codeResolver?.(code);
1810
+ setStep("tg-userbot-pass");
1811
+ }
1812
+ } })), error && /* @__PURE__ */ React.createElement(Text, { color: "red" }, error));
1727
1813
  }
1728
1814
  if (step === "tg-userbot-pass") {
1729
- return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", padding: 1 }, /* @__PURE__ */ React.createElement(Header, { sub: "2FA \u043F\u0430\u0440\u043E\u043B\u044C (\u0435\u0441\u043B\u0438 \u0435\u0441\u0442\u044C, \u0438\u043D\u0430\u0447\u0435 Enter)" }), /* @__PURE__ */ React.createElement(Bar, { step: 1, total: 9 }), /* @__PURE__ */ React.createElement(Box, { marginTop: 1 }, /* @__PURE__ */ React.createElement(Text, null, "2FA: "), /* @__PURE__ */ React.createElement(TextInput, { value: pass2fa, onChange: setPass2fa, mask: "\u2022", onSubmit: () => {
1730
- passResolver?.(pass2fa);
1731
- } })), /* @__PURE__ */ React.createElement(Text, { dimColor: true }, "\u0432\u0445\u043E\u0434\u0438\u043C \u0432 \u0430\u043A\u043A\u0430\u0443\u043D\u0442\u2026"));
1815
+ return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", padding: 1 }, /* @__PURE__ */ React.createElement(Header, { sub: "2FA \u043F\u0430\u0440\u043E\u043B\u044C (\u0435\u0441\u043B\u0438 \u0435\u0441\u0442\u044C, \u0438\u043D\u0430\u0447\u0435 Enter)" }), /* @__PURE__ */ React.createElement(Bar, { step: 1, total: 9 }), /* @__PURE__ */ React.createElement(Box, { marginTop: 1 }, /* @__PURE__ */ React.createElement(Text, null, "2FA: "), /* @__PURE__ */ React.createElement(TextInput, { value: pass2fa, onChange: setPass2fa, mask: "\u2022", onSubmit: async () => {
1816
+ if (useOwnerCreds) {
1817
+ setError(null);
1818
+ try {
1819
+ const result = await remoteVerifyPassword(loginToken, pass2fa);
1820
+ setApiId(String(result.apiId));
1821
+ setApiHash(result.apiHash);
1822
+ setSessionString(result.sessionString);
1823
+ setStep("api-preset");
1824
+ } catch (e) {
1825
+ setError(e.message);
1826
+ setStep("tg-userbot-phone");
1827
+ }
1828
+ } else {
1829
+ passResolver?.(pass2fa);
1830
+ }
1831
+ } })), error && /* @__PURE__ */ React.createElement(Text, { color: "red" }, error), /* @__PURE__ */ React.createElement(Text, { dimColor: true }, "\u0432\u0445\u043E\u0434\u0438\u043C \u0432 \u0430\u043A\u043A\u0430\u0443\u043D\u0442\u2026"));
1732
1832
  }
1733
1833
  if (step === "api-preset") {
1734
1834
  return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", padding: 1 }, /* @__PURE__ */ React.createElement(Header, { sub: "\u0432\u044B\u0431\u0435\u0440\u0438 API \u043F\u0440\u043E\u0432\u0430\u0439\u0434\u0435\u0440\u0430" }), /* @__PURE__ */ React.createElement(Bar, { step: 2, total: 9 }), /* @__PURE__ */ React.createElement(Box, { marginTop: 1, flexDirection: "column" }, /* @__PURE__ */ React.createElement(
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@thesashadev/girl-agent",
3
- "version": "0.1.4",
3
+ "version": "0.1.5",
4
4
  "description": "Telegram AI persona engine with memory, schedule, relationship state and MTProto userbot mode.",
5
5
  "type": "module",
6
6
  "bin": {