izteamslots 1.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 +1 -0
- package/CONTRIBUTING.md +128 -0
- package/README.md +249 -0
- package/app.py +25 -0
- package/backend/__init__.py +3 -0
- package/backend/__main__.py +3 -0
- package/backend/account_store.py +448 -0
- package/backend/chatgpt_workspace_api.py +104 -0
- package/backend/dto.py +106 -0
- package/backend/file_logger.py +82 -0
- package/backend/jobs.py +77 -0
- package/backend/mail/__init__.py +98 -0
- package/backend/mail/base.py +86 -0
- package/backend/mail/boomlify.py +178 -0
- package/backend/mail/imap.py +221 -0
- package/backend/mail/trickads.py +121 -0
- package/backend/openai_web_auth.py +1402 -0
- package/backend/rpc_protocol.py +78 -0
- package/backend/rpc_server.py +233 -0
- package/backend/slot_orchestrator.py +400 -0
- package/backend/ui_facade.py +368 -0
- package/bin/izteamslots.sh +16 -0
- package/package.json +30 -0
- package/requirements.txt +2 -0
- package/scripts/setup.sh +82 -0
- package/ui/package.json +19 -0
- package/ui/src/main.ts +4 -0
- package/ui/src/menus/format.ts +163 -0
- package/ui/src/menus/mainMenus.ts +221 -0
- package/ui/src/menus/types.ts +75 -0
- package/ui/src/screens/MainScreen.ts +1175 -0
- package/ui/src/transport/stdioClient.ts +162 -0
- package/ui/tsconfig.json +13 -0
package/.env.example
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
BOOMLIFY_API_KEY=your_boomlify_api_key_here
|
package/CONTRIBUTING.md
ADDED
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
# Участие в разработке izTeamSlots
|
|
2
|
+
|
|
3
|
+
Спасибо за интерес к проекту! Это руководство поможет начать.
|
|
4
|
+
|
|
5
|
+
## Подготовка окружения
|
|
6
|
+
|
|
7
|
+
1. Форкните репозиторий
|
|
8
|
+
2. Клонируйте форк:
|
|
9
|
+
```bash
|
|
10
|
+
git clone https://github.com/<your-username>/izTeamSlots.git
|
|
11
|
+
cd izTeamSlots
|
|
12
|
+
```
|
|
13
|
+
3. Установите зависимости:
|
|
14
|
+
```bash
|
|
15
|
+
npm install
|
|
16
|
+
```
|
|
17
|
+
Скрипт автоматически поставит Python 3.11+, [uv](https://docs.astral.sh/uv/), [Bun](https://bun.sh) и все зависимости.
|
|
18
|
+
|
|
19
|
+
4. Создайте `.env` и добавьте ключи:
|
|
20
|
+
```bash
|
|
21
|
+
cp .env.example .env
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
5. Создайте ветку:
|
|
25
|
+
```bash
|
|
26
|
+
git checkout -b feat/my-feature
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Структура проекта
|
|
30
|
+
|
|
31
|
+
```text
|
|
32
|
+
izTeamSlots/
|
|
33
|
+
├── backend/ # Python — бизнес-логика, браузерная автоматизация
|
|
34
|
+
│ ├── mail/ # Почтовые провайдеры (плагины)
|
|
35
|
+
│ ├── openai_web_auth.py
|
|
36
|
+
│ ├── slot_orchestrator.py
|
|
37
|
+
│ └── ui_facade.py
|
|
38
|
+
├── ui/ # TypeScript — терминальный интерфейс (OpenTUI)
|
|
39
|
+
│ └── src/
|
|
40
|
+
├── bin/ # CLI entrypoint (npm bin)
|
|
41
|
+
├── scripts/ # Setup-скрипты
|
|
42
|
+
└── .github/workflows/ # CI/CD
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## Линтеры
|
|
46
|
+
|
|
47
|
+
Перед коммитом убедитесь что код проходит проверки:
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
# Python — ruff
|
|
51
|
+
ruff check backend/
|
|
52
|
+
|
|
53
|
+
# TypeScript — tsc
|
|
54
|
+
npm run typecheck:ui
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
CI автоматически запускает оба линтера на каждый push и PR.
|
|
58
|
+
|
|
59
|
+
## Conventional Commits
|
|
60
|
+
|
|
61
|
+
Проект использует [Conventional Commits](https://www.conventionalcommits.org/):
|
|
62
|
+
|
|
63
|
+
| Префикс | Назначение |
|
|
64
|
+
|---------|-----------|
|
|
65
|
+
| `feat:` | Новая функциональность |
|
|
66
|
+
| `fix:` | Исправление бага |
|
|
67
|
+
| `docs:` | Только документация |
|
|
68
|
+
| `chore:` | CI, скрипты, зависимости |
|
|
69
|
+
| `refactor:` | Рефакторинг без изменения поведения |
|
|
70
|
+
|
|
71
|
+
Примеры:
|
|
72
|
+
```
|
|
73
|
+
feat: add IMAP mail provider
|
|
74
|
+
fix: handle Oops error page during OAuth
|
|
75
|
+
chore: update seleniumbase to 4.33
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
Версия бампается автоматически:
|
|
79
|
+
- `feat:` — minor (1.x.0)
|
|
80
|
+
- `fix:` / `chore:` — patch (1.0.x)
|
|
81
|
+
- `feat!:` / `BREAKING CHANGE` — major (x.0.0)
|
|
82
|
+
|
|
83
|
+
## Как внести вклад
|
|
84
|
+
|
|
85
|
+
### Баг-репорты
|
|
86
|
+
|
|
87
|
+
Откройте issue с:
|
|
88
|
+
- Шаги для воспроизведения
|
|
89
|
+
- Ожидаемое vs фактическое поведение
|
|
90
|
+
- Версия Python, ОС, лог ошибки
|
|
91
|
+
|
|
92
|
+
### Новая функциональность
|
|
93
|
+
|
|
94
|
+
Откройте issue с описанием:
|
|
95
|
+
- Какую проблему решает
|
|
96
|
+
- Предлагаемое решение
|
|
97
|
+
- К какому модулю относится
|
|
98
|
+
|
|
99
|
+
### Pull Requests
|
|
100
|
+
|
|
101
|
+
1. Один PR — одно логическое изменение.
|
|
102
|
+
2. Следуйте Conventional Commits.
|
|
103
|
+
3. Убедитесь что `ruff check` и `tsc --noEmit` проходят.
|
|
104
|
+
4. Обновите документацию если изменение затрагивает пользовательское поведение.
|
|
105
|
+
|
|
106
|
+
### Новый почтовый провайдер
|
|
107
|
+
|
|
108
|
+
Наследуйте `MailProvider` из `backend/mail/base.py`:
|
|
109
|
+
|
|
110
|
+
```python
|
|
111
|
+
from backend.mail.base import MailProvider, Mailbox, Inbox
|
|
112
|
+
|
|
113
|
+
class MyProvider(MailProvider):
|
|
114
|
+
name = "my_provider"
|
|
115
|
+
|
|
116
|
+
def generate(self) -> Mailbox:
|
|
117
|
+
...
|
|
118
|
+
|
|
119
|
+
def inbox(self, mailbox: Mailbox) -> Inbox:
|
|
120
|
+
...
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
Зарегистрируйте в `backend/mail/__init__.py` в фабричных функциях.
|
|
124
|
+
|
|
125
|
+
## Важно
|
|
126
|
+
|
|
127
|
+
- **Никогда** не коммитьте `.env`, `accounts/`, `codex/` — они в `.gitignore`.
|
|
128
|
+
- Токены и профили хранятся только локально.
|
package/README.md
ADDED
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
<div align="center">
|
|
2
|
+
|
|
3
|
+
# izTeamSlots
|
|
4
|
+
|
|
5
|
+
**Менеджер ChatGPT Team слотов с авто-регистрацией через временную почту и обновлением Codex-сессий**
|
|
6
|
+
|
|
7
|
+
[](https://github.com/izzzzzi/izTeamSlots/actions/workflows/ci.yml)
|
|
8
|
+
[](https://github.com/izzzzzi/izTeamSlots/actions/workflows/release.yml)
|
|
9
|
+
[](https://www.npmjs.com/package/izteamslots)
|
|
10
|
+
[](LICENSE)
|
|
11
|
+
[](https://python.org/)
|
|
12
|
+
[](https://www.typescriptlang.org/)
|
|
13
|
+
[](https://bun.sh/)
|
|
14
|
+
|
|
15
|
+
<br />
|
|
16
|
+
|
|
17
|
+
<img src="img/demo.gif" alt="izTeamSlots demo" width="600" />
|
|
18
|
+
|
|
19
|
+
</div>
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## Обзор
|
|
24
|
+
|
|
25
|
+
**izTeamSlots** — локальное приложение с архитектурой:
|
|
26
|
+
|
|
27
|
+
- **Python backend** (бизнес-логика, браузерная автоматизация, storage);
|
|
28
|
+
- **TypeScript OpenTUI frontend** (терминальный интерфейс оператора).
|
|
29
|
+
|
|
30
|
+
---
|
|
31
|
+
|
|
32
|
+
## Возможности
|
|
33
|
+
|
|
34
|
+
- Управление админами: добавить, перелогинить, удалить, открыть браузерный профиль.
|
|
35
|
+
- Пайплайн слотов: `создать почту -> инвайт -> регистрация -> OAuth-логин`.
|
|
36
|
+
- Перелогин слотов: одного выбранного или всех по очереди.
|
|
37
|
+
- Codex-файлы: авто-сохранение `codex-<email>-Team.json` в аккаунт и в `./codex/`.
|
|
38
|
+
- Doctor-проверка: валидация/восстановление файловой структуры аккаунтов при старте.
|
|
39
|
+
- Просмотр почты: входящие письма для админов и слотов.
|
|
40
|
+
|
|
41
|
+
---
|
|
42
|
+
|
|
43
|
+
## Структура проекта
|
|
44
|
+
|
|
45
|
+
```text
|
|
46
|
+
izTeamSlots/
|
|
47
|
+
├── app.py # Entrypoint: запускает UI
|
|
48
|
+
├── backend/ # Весь Python-бэкенд
|
|
49
|
+
│ ├── __init__.py # PROJECT_ROOT
|
|
50
|
+
│ ├── __main__.py # python -m backend
|
|
51
|
+
│ ├── account_store.py # CRUD аккаунтов (JSON storage)
|
|
52
|
+
│ ├── mail/ # Почтовые провайдеры (плагины)
|
|
53
|
+
│ │ ├── __init__.py # Фабрики: create_provider, create_slot_provider
|
|
54
|
+
│ │ ├── base.py # MailProvider ABC, Mailbox, Mail, Inbox
|
|
55
|
+
│ │ ├── boomlify.py # Boomlify Temp Mail API
|
|
56
|
+
│ │ ├── trickads.py # trickadsagencyltd.com temp mail
|
|
57
|
+
│ │ └── imap.py # Любой IMAP-сервер
|
|
58
|
+
│ ├── openai_web_auth.py # Браузерная автоматизация (SeleniumBase)
|
|
59
|
+
│ ├── chatgpt_workspace_api.py # ChatGPT Workspace API через браузер
|
|
60
|
+
│ ├── slot_orchestrator.py # Оркестратор пайплайна слотов
|
|
61
|
+
│ ├── dto.py # DTO для UI
|
|
62
|
+
│ ├── jobs.py # Задачи в потоках
|
|
63
|
+
│ ├── rpc_protocol.py # JSON-RPC протокол
|
|
64
|
+
│ ├── rpc_server.py # RPC-сервер (stdio)
|
|
65
|
+
│ └── ui_facade.py # Фасад между RPC и бизнес-логикой
|
|
66
|
+
├── ui/ # TypeScript TUI (OpenTUI)
|
|
67
|
+
│ ├── package.json
|
|
68
|
+
│ └── src/
|
|
69
|
+
│ ├── main.ts # Entrypoint UI
|
|
70
|
+
│ ├── screens/MainScreen.ts # Главный экран
|
|
71
|
+
│ ├── transport/stdioClient.ts # JSON-RPC клиент
|
|
72
|
+
│ └── menus/ # Меню, таблицы, форматирование
|
|
73
|
+
├── accounts/ # Данные аккаунтов (runtime)
|
|
74
|
+
├── codex/ # Codex-файлы (runtime)
|
|
75
|
+
└── README.md
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
---
|
|
79
|
+
|
|
80
|
+
## Установка
|
|
81
|
+
|
|
82
|
+
### npm (рекомендуется)
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
npm install -g izteamslots
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
Или запуск без установки:
|
|
89
|
+
|
|
90
|
+
```bash
|
|
91
|
+
npx izteamslots
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
### Из исходников
|
|
95
|
+
|
|
96
|
+
```bash
|
|
97
|
+
git clone https://github.com/izzzzzi/izTeamSlots.git
|
|
98
|
+
cd izTeamSlots
|
|
99
|
+
npm install
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
`npm install` / `postinstall` автоматически:
|
|
103
|
+
- Проверит Python 3.11+
|
|
104
|
+
- Установит [uv](https://docs.astral.sh/uv/) если его нет (быстрый Python package manager)
|
|
105
|
+
- Установит Python-зависимости через uv (`seleniumbase`, `requests`)
|
|
106
|
+
- Установит [Bun](https://bun.sh) если его нет + UI-зависимости
|
|
107
|
+
- Создаст `.env` из `.env.example` если его нет
|
|
108
|
+
|
|
109
|
+
> Chrome и chromedriver скачиваются автоматически при первом запуске через SeleniumBase.
|
|
110
|
+
|
|
111
|
+
Если нужно перезапустить setup вручную:
|
|
112
|
+
|
|
113
|
+
```bash
|
|
114
|
+
npm run setup
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
### Настройка .env
|
|
118
|
+
|
|
119
|
+
```bash
|
|
120
|
+
# Temp mail API (обязательно для создания слотов)
|
|
121
|
+
BOOMLIFY_API_KEY=your_api_key
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
Опциональные переменные:
|
|
125
|
+
|
|
126
|
+
| Переменная | По умолчанию | Описание |
|
|
127
|
+
|-----------|:------------:|----------|
|
|
128
|
+
| `BOOMLIFY_DOMAIN` | авто | Домен для временных почт |
|
|
129
|
+
| `BOOMLIFY_TIME` | `permanent` | Время жизни ящика |
|
|
130
|
+
| `SLOT_MAIL_PROVIDER` | `boomlify` | Провайдер почты для слотов |
|
|
131
|
+
| `MAIL_PROVIDER` | `trickads` | Провайдер почты для админов |
|
|
132
|
+
|
|
133
|
+
## Запуск
|
|
134
|
+
|
|
135
|
+
```bash
|
|
136
|
+
# Глобальная установка
|
|
137
|
+
izteamslots
|
|
138
|
+
|
|
139
|
+
# Из исходников
|
|
140
|
+
npm start
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
Это запустит OpenTUI frontend через **Bun**, который поднимет Python RPC backend (`python -m backend`) по `stdio`.
|
|
144
|
+
|
|
145
|
+
---
|
|
146
|
+
|
|
147
|
+
## Архитектура
|
|
148
|
+
|
|
149
|
+
```mermaid
|
|
150
|
+
flowchart TD
|
|
151
|
+
A[app.py] -->|spawns| B[bun ui/src/main.ts]
|
|
152
|
+
B --> C[MainScreen.ts]
|
|
153
|
+
C -->|stdio JSON-RPC| D[StdioRpcClient]
|
|
154
|
+
D -->|spawns| E[python -m backend]
|
|
155
|
+
E --> F[RPCServer]
|
|
156
|
+
F --> G[UIFacade]
|
|
157
|
+
G --> H[AccountStore]
|
|
158
|
+
G --> I[SlotManager]
|
|
159
|
+
I --> J[openai_web_auth]
|
|
160
|
+
I --> K[chatgpt_workspace_api]
|
|
161
|
+
I --> L[Boomlify Mail API]
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
## Почтовые провайдеры (плагины)
|
|
165
|
+
|
|
166
|
+
Система почты построена на плагинах — абстрактный класс `MailProvider` и конкретные реализации.
|
|
167
|
+
|
|
168
|
+
```mermaid
|
|
169
|
+
flowchart TD
|
|
170
|
+
MP[MailProvider — абстрактный класс]
|
|
171
|
+
MP --> B[BoomlifyProvider]
|
|
172
|
+
MP --> T[TrickAdsProvider]
|
|
173
|
+
MP --> I[IMAPProvider]
|
|
174
|
+
|
|
175
|
+
CF[create_provider] -->|MAIL_PROVIDER env| MP
|
|
176
|
+
CSP[create_slot_provider] -->|SLOT_MAIL_PROVIDER env| MP
|
|
177
|
+
CPM[create_provider_for_mailbox] -->|по формату password| MP
|
|
178
|
+
|
|
179
|
+
style MP fill:#1e3a5f,color:#fff
|
|
180
|
+
style B fill:#1a4731,color:#fff
|
|
181
|
+
style T fill:#1a4731,color:#fff
|
|
182
|
+
style I fill:#1a4731,color:#fff
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
### Встроенные провайдеры
|
|
186
|
+
|
|
187
|
+
| Провайдер | Модуль | Описание | Env-переменные |
|
|
188
|
+
|-----------|--------|----------|----------------|
|
|
189
|
+
| `boomlify` | `mail/boomlify.py` | Boomlify Temp Mail API (по умолчанию для слотов) | `BOOMLIFY_API_KEY`, `BOOMLIFY_DOMAIN`, `BOOMLIFY_TIME` |
|
|
190
|
+
| `trickads` | `mail/trickads.py` | trickadsagencyltd.com temp mail (по умолчанию для админов) | — |
|
|
191
|
+
| `imap` | `mail/imap.py` | Любой IMAP-сервер | `IMAP_HOST`, `IMAP_PORT`, `IMAP_SSL`, `IMAP_FOLDER` |
|
|
192
|
+
|
|
193
|
+
### Фабричные функции
|
|
194
|
+
|
|
195
|
+
- `create_provider(name)` — создаёт провайдер по имени (или `MAIL_PROVIDER` env, по умолчанию `trickads`)
|
|
196
|
+
- `create_slot_provider(name)` — для слотов (`SLOT_MAIL_PROVIDER` env, по умолчанию `boomlify`)
|
|
197
|
+
- `create_provider_for_mailbox(mailbox)` — автоопределение по формату пароля (если `boomlify:<uuid>` → Boomlify)
|
|
198
|
+
|
|
199
|
+
### Свой провайдер
|
|
200
|
+
|
|
201
|
+
Наследуйте `MailProvider` из `backend/mail/base.py` и реализуйте два метода:
|
|
202
|
+
|
|
203
|
+
```python
|
|
204
|
+
from backend.mail.base import MailProvider, Mailbox, Inbox
|
|
205
|
+
|
|
206
|
+
class MyProvider(MailProvider):
|
|
207
|
+
name = "my_provider"
|
|
208
|
+
|
|
209
|
+
def generate(self) -> Mailbox:
|
|
210
|
+
# создать временный ящик, вернуть Mailbox(email, password)
|
|
211
|
+
...
|
|
212
|
+
|
|
213
|
+
def inbox(self, mailbox: Mailbox) -> Inbox:
|
|
214
|
+
# получить письма, вернуть Inbox(email, messages=[Mail(...), ...])
|
|
215
|
+
...
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
---
|
|
219
|
+
|
|
220
|
+
## Пайплайн слотов
|
|
221
|
+
|
|
222
|
+
```mermaid
|
|
223
|
+
flowchart TD
|
|
224
|
+
S1[Создать временную почту] --> S2[Отправить инвайт через API]
|
|
225
|
+
S2 --> S3[Ожидать письмо с инвайт-ссылкой]
|
|
226
|
+
S3 --> S4[Регистрация по ссылке в браузере]
|
|
227
|
+
S4 --> S5[Ввод email / пароль / код подтверждения]
|
|
228
|
+
S5 --> S6[Заполнение имени и даты рождения]
|
|
229
|
+
S6 --> S7[Закрыть браузер регистрации]
|
|
230
|
+
S7 --> S8[OAuth PKCE логин]
|
|
231
|
+
S8 --> S9[Сохранить access_token и codex-файл]
|
|
232
|
+
|
|
233
|
+
style S1 fill:#1e3a5f,color:#fff
|
|
234
|
+
style S9 fill:#1a4731,color:#fff
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
---
|
|
238
|
+
|
|
239
|
+
## Важно
|
|
240
|
+
|
|
241
|
+
- Проект хранит токены и браузерные профили локально на диске.
|
|
242
|
+
- Не публикуйте папки `accounts/` и `codex/` в публичные репозитории.
|
|
243
|
+
- Для стабильной работы перелогина у worker должен быть `openai_password`.
|
|
244
|
+
|
|
245
|
+
---
|
|
246
|
+
|
|
247
|
+
## Участие в разработке
|
|
248
|
+
|
|
249
|
+
См. [CONTRIBUTING.md](CONTRIBUTING.md).
|
package/app.py
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import os
|
|
4
|
+
import subprocess
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def main() -> int:
|
|
9
|
+
root = Path(__file__).resolve().parent
|
|
10
|
+
ui_dir = root / "ui"
|
|
11
|
+
|
|
12
|
+
if not ui_dir.exists():
|
|
13
|
+
raise RuntimeError("ui/ не найден")
|
|
14
|
+
|
|
15
|
+
bun_bin = os.environ.get("BUN_BIN", "bun")
|
|
16
|
+
env = {
|
|
17
|
+
**os.environ,
|
|
18
|
+
"IZTEAMSLOTS_AUTOMIGRATE_PROFILES": os.environ.get("IZTEAMSLOTS_AUTOMIGRATE_PROFILES", "0"),
|
|
19
|
+
}
|
|
20
|
+
cmd = [bun_bin, "run", "src/main.ts"]
|
|
21
|
+
return subprocess.call(cmd, cwd=ui_dir, env=env)
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
if __name__ == "__main__":
|
|
25
|
+
raise SystemExit(main())
|