Перейти к содержимому

Установка

Вопрос, на который здесь есть ответ: что и куда я ставлю, и где на самом деле живут разговоры?

Каждая машина запускает весь продукт и хранит собственную копию журнала событий. Одна из них - дом (home); остальные - клиенты. Клиент отправляет то, что записал, домой и слушает всё остальное; дом раздаёт дальше.

Дом - не мастер. Он хранит тот же подписанный журнал, что и все остальные; если он сгорит, на каждой машине останется весь разговор, и любая из них может стать домом сменой одной настройки. Он существует потому, что до закрытого ноутбука не достучаться, а два ноутбука, никогда не открытые одновременно, никогда не сойдутся.

Машина, у которой не настроен адрес дома, и есть дом. Это же и случай одной машины: свежая установка разговаривает сама с собой и не требует никакой настройки.

Четыре схемы; разница в том, какая машина может дозвониться до какой. Выберите одну в Settings → Relay на доме; каждая другая машина считает выбор из журнала.

Что это Нужен секрет
Одна локальная сеть Все машины в одном здании. Ничего не ставить; ничего не работает вне этой сети. Нет
Tailscale Каждая машина получает адрес, работающий откуда угодно, за любым NAT. Нет - tailnet приватна
Одна постоянно включённая машина дома Вариант по умолчанию. Клиенты дозваниваются, где бы они ни были. Нет
Дом на публичном адресе VPS или порт, проброшенный на машину дома. Да - настройка отказывает без него

Клиент только дозванивается наружу, поэтому машина за carrier NAT или за хотспотом уже сегодня работает как клиент; она просто не может быть той машиной, до которой дозваниваются все. Публичный адрес - тот, к которому может присоединиться интернет - сначала задайте MAVEN_TEAMS_SECRET одинаковой строкой на каждой машине. Это не шифрование; оно покупает ровно одно свойство - посторонний не сможет присоединиться. Задайте его везде за один присест: отказ здесь тихий.

Node 22.22+ (ради node:sqlite), git, POSIX-shell.

Terminal window
git clone <your-repository-url> ~/maven-teams
cd ~/maven-teams
npm ci
npm run build
npm start # http://localhost:3400

Скопируйте .env.example в .env.local и заполните ключи, которые у вас есть; все они опциональны. Переменные, которые решают, как машина ведёт себя в сети:

Переменная Что делает
MAVEN_STATE_DIR Где живут журнал, ключ подписи, настройки и задачи. По умолчанию ~/.maven-teams - намеренно не ~/.maven M.A.V.E.N, с которым у неё семнадцать общих имён файлов.
MAVEN_MACHINE Имя этой машины в журнале и в каждой строке аудита. По умолчанию - hostname.
MAVEN_HOME_URL Адрес дома. Задайте - и эта машина клиент; оставьте пустым - и она дом. Settings → Relay тоже может задать его, без перезапуска; если есть и то и другое, побеждает переменная.
MAVEN_TEAMS_SECRET Общий секрет рабочего пространства. Отсутствует - значит открыто: правильно за роутером, неправильно на публичном адресе.
MAVEN_FORCE_CLOUD 1 отправляет каждую возможность к провайдеру независимо от железа. См. Вычисления.
PORT / HOST По умолчанию 3000 / 127.0.0.1; служба задаёт 3400. Машине, до которой должны достучаться другие, нужен HOST=0.0.0.0.

Объявляемый адрес машины читается из её сетевого интерфейса; а то, на чём она слушает, - это HOST. Оставьте значение по умолчанию - и машина уверенно опубликует http://192.168.1.42:3400, принимая при этом только соединения от самой себя: как клиент она работает идеально, домом быть не может никогда, и каждый экран говорит, что всё хорошо.

Environment=HOST=0.0.0.0
Environment=PORT=3400

Пользовательская служба systemd - чтобы она работала от вашего имени и могла читать ваши ключи:

~/.config/systemd/user/maven-teams.service
[Unit]
Description=MAVEN Teams
After=network-online.target
[Service]
WorkingDirectory=%h/maven-teams
Environment=NODE_ENV=production
Environment=PORT=3400
Environment=MAVEN_MACHINE=%H
ExecStart=/usr/bin/npm run start
Restart=always
[Install]
WantedBy=default.target
Terminal window
systemctl --user daemon-reload
systemctl --user enable --now maven-teams
loginctl enable-linger "$USER" # or it stops when you log out

На доме откройте Settings → Relay. Под первой строкой - «reach me at» - адреса, которые может использовать другая машина, порт уже подставлен. Скопируйте один. На каждом клиенте вставьте его в поле дома и нажмите SET HOME. Через несколько секунд панель скажет connected, и вся история рабочего пространства приедет.

Чтобы позже перенести дом, нажмите MAKE THIS MACHINE THE HOME на новой машине и задайте её адрес на остальных. Ничего не теряется: журнал уже есть на каждой машине.

Если клиент не может достучаться до дома, проверьте то направление, которое важно - с клиента:

Terminal window
curl -s -o /dev/null -w '%{http_code}\n' --max-time 5 http://<home-address>:3400/api/relay

200 означает, что с сетью всё в порядке и проблема в конфигурации. Для сетей, которые не видят друг друга, поставьте машины на WireGuard или Tailscale и используйте тот адрес; каждая машина объявляет все адреса, какие у неё есть.

Terminal window
curl -s localhost:3400/api/relay | jq '{me: .me.machine, role: .hub.role, connected: .hub.connected}'
curl -s localhost:3400/api/events/verify | jq

Цепочка каждой машины проверяется отдельно; ok: false называет порядковый номер, на котором разрыв.

$MAVEN_STATE_DIR/ (defaults to ~/.maven-teams)
├── events/
│ ├── log.jsonl this machine's own chain - the one it signs
│ └── peers/<machine>.jsonl one file per machine, exactly as received
├── teams/
│ ├── identity.json this machine's keypair. BACK THIS UP.
│ ├── peers.json addresses of machines to pull from directly
│ └── hub.json the home's address, if this machine is a client
└── index.db SQLite full-text index - derived, delete it freely

identity.json - единственный незаменимый файл. Потеряете его - машина не сможет подписывать новые события; новая идентичность означает новую цепочку под тем же именем. index.db можно выбросить - если поиск ведёт себя странно, удалите его.

Разговоры, которые вы очищаете, также записываются в ваше хранилище (vault) Obsidian как Markdown в memories/channels/<room>/.

Журнал несёт то, что произошло: сообщения, патчи, прогоны, согласования, решения. Он не несёт ваши ключи - .env.local остаётся на машине, где был написан, а агенты работают на той машине, за которой вы сидите, с вашими учётными данными. Приватный канал скрыт, а не зашифрован: журнал реплицируется повсюду; настройка решает, что показывает интерфейс.