@deadragdoll/tellymcp 0.0.10 → 0.0.12
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.client +42 -52
- package/.env.example.gateway +48 -62
- package/CHANGELOG.md +3 -3
- package/README-ru.md +226 -376
- package/README.md +213 -1184
- package/TOOLS.md +320 -377
- package/VERSION.md +13 -13
- package/config/codex/plugins/telly-workflows/.codex-plugin/plugin.json +18 -0
- package/config/codex/plugins/telly-workflows/references/invariants.md +10 -0
- package/config/codex/plugins/telly-workflows/skills/telly-browser-screenshot/SKILL.md +27 -0
- package/config/codex/plugins/telly-workflows/skills/telly-collab-artifact/SKILL.md +22 -0
- package/config/codex/plugins/telly-workflows/skills/telly-human-telegram/SKILL.md +31 -0
- package/config/codex/plugins/telly-workflows/skills/telly-partner-note/SKILL.md +36 -0
- package/config/templates/env.both.template +39 -20
- package/config/templates/env.client.template +34 -19
- package/config/templates/env.gateway.template +37 -22
- package/dist/cli.js +322 -75
- package/dist/codexPluginInstaller.js +215 -0
- package/dist/lib/mixins/session.errors.js +34 -1
- package/dist/lib/pinoTargets.js +2 -2
- package/dist/moleculer.config.js +7 -5
- package/dist/services/features/telegram-mcp/browser.service.js +94 -1
- package/dist/services/features/telegram-mcp/collaboration.service.js +40 -3
- package/dist/services/features/telegram-mcp/ensuredb.service.js +145 -26
- package/dist/services/features/telegram-mcp/gateway-delivery.service.js +285 -103
- package/dist/services/features/telegram-mcp/gateway-socket.service.js +907 -85
- package/dist/services/features/telegram-mcp/gateway.service.js +876 -81
- package/dist/services/features/telegram-mcp/mcp-http.service.js +8 -0
- package/dist/services/features/telegram-mcp/mcp-server.service.js +17 -26
- package/dist/services/features/telegram-mcp/notify.service.js +127 -1
- package/dist/services/features/telegram-mcp/session-context.service.js +28 -1
- package/dist/services/features/telegram-mcp/src/app/bootstrap/runtime.js +132 -10
- package/dist/services/features/telegram-mcp/src/app/config/env.js +158 -52
- package/dist/services/features/telegram-mcp/src/app/http.js +375 -42
- package/dist/services/features/telegram-mcp/src/app/webapp/assets.js +386 -58
- package/dist/services/features/telegram-mcp/src/app/webapp/auth.js +3 -0
- package/dist/services/features/telegram-mcp/src/app/webapp/terminal.js +12 -0
- package/dist/services/features/telegram-mcp/src/entities/request/model/schema.js +120 -104
- package/dist/services/features/telegram-mcp/src/entities/xchange/model/types.js +2 -0
- package/dist/services/features/telegram-mcp/src/features/ask-user/model/askUserTelegram.js +1 -1
- package/dist/services/features/telegram-mcp/src/features/browser/model/browserOpenTool.js +1 -1
- package/dist/services/features/telegram-mcp/src/features/browser/model/browserScreenshotTool.js +1 -1
- package/dist/services/features/telegram-mcp/src/features/browser/model/browserService.js +306 -26
- package/dist/services/features/telegram-mcp/src/features/collaboration/model/gatewaySessionsService.js +71 -0
- package/dist/services/features/telegram-mcp/src/features/collaboration/model/listGatewaySessionsTool.js +33 -0
- package/dist/services/features/telegram-mcp/src/features/collaboration/model/localCollaborationBackend.js +93 -82
- package/dist/services/features/telegram-mcp/src/features/collaboration/model/sendPartnerFileService.js +47 -5
- package/dist/services/features/telegram-mcp/src/features/collaboration/model/sendPartnerFileTool.js +1 -1
- package/dist/services/features/telegram-mcp/src/features/collaboration/model/sendPartnerNoteTool.js +1 -1
- package/dist/services/features/telegram-mcp/src/features/distributed-client/model/gatewayClientAccess.js +82 -0
- package/dist/services/features/telegram-mcp/src/features/distributed-client/model/gatewayCollaborationBackend.js +22 -14
- package/dist/services/features/telegram-mcp/src/features/distributed-gateway/model/gatewayHttpService.js +697 -75
- package/dist/services/features/telegram-mcp/src/features/distributed-gateway/model/remoteConsoleActionClient.js +76 -0
- package/dist/services/features/telegram-mcp/src/features/embedded-runtime/model/embeddedRuntimeBroker.js +92 -0
- package/dist/services/features/telegram-mcp/src/features/foreground-terminal/model/foregroundTerminalRuntime.js +192 -0
- package/dist/services/features/telegram-mcp/src/features/notify/model/notifyService.js +382 -3
- package/dist/services/features/telegram-mcp/src/features/notify/model/notifyTelegramTool.js +1 -1
- package/dist/services/features/telegram-mcp/src/features/notify/model/sendFileToTelegramTool.js +33 -0
- package/dist/services/features/telegram-mcp/src/features/session-context/model/clearSessionContextTool.js +1 -1
- package/dist/services/features/telegram-mcp/src/features/session-context/model/getSessionContextTool.js +1 -1
- package/dist/services/features/telegram-mcp/src/features/session-context/model/renameSessionTool.js +1 -1
- package/dist/services/features/telegram-mcp/src/features/session-context/model/sessionContextService.js +42 -200
- package/dist/services/features/telegram-mcp/src/features/session-context/model/setSessionContextTool.js +1 -1
- package/dist/services/features/telegram-mcp/src/features/terminal-buffer/model/terminalBufferService.js +96 -0
- package/dist/services/features/telegram-mcp/src/features/terminal-input/model/terminalInputService.js +97 -0
- package/dist/services/features/telegram-mcp/src/features/tools-sync/model/refreshToolsMarkdownService.js +107 -58
- package/dist/services/features/telegram-mcp/src/features/tools-sync/model/refreshToolsMarkdownTool.js +1 -1
- package/dist/services/features/telegram-mcp/src/features/xchange/model/getXchangeRecordTool.js +28 -0
- package/dist/services/features/telegram-mcp/src/features/xchange/model/listXchangeRecordsTool.js +28 -0
- package/dist/services/features/telegram-mcp/src/features/xchange/model/markXchangeRecordReadTool.js +28 -0
- package/dist/services/features/telegram-mcp/src/features/xchange/model/xchangeService.js +169 -0
- package/dist/services/features/telegram-mcp/src/processes/human-approval/model/orchestrator.js +5 -4
- package/dist/services/features/telegram-mcp/src/shared/i18n/resources/en.js +143 -42
- package/dist/services/features/telegram-mcp/src/shared/i18n/resources/ru.js +139 -38
- package/dist/services/features/telegram-mcp/src/shared/integrations/memory/processLocalSessionStore.js +27 -0
- package/dist/services/features/telegram-mcp/src/shared/integrations/object-storage/minioExchangeStore.js +11 -8
- package/dist/services/features/telegram-mcp/src/shared/integrations/redis/stateStore.js +69 -70
- package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/proxyFetch.js +21 -22
- package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transport.js +444 -7093
- package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportAttachmentStore.js +93 -0
- package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportBroadcastActions.js +385 -0
- package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportConsoleRegistry.js +149 -0
- package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportConstructorWiring.js +642 -0
- package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportContent.js +84 -0
- package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportContext.js +78 -0
- package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportDocumentActions.js +36 -0
- package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportEventActions.js +292 -0
- package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportFileHandoffActions.js +352 -0
- package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportFormatting.js +75 -0
- package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportGatewayActions.js +44 -0
- package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportLifecycleActions.js +161 -0
- package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportLive.js +56 -0
- package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportLiveActions.js +77 -0
- package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportMenuCallbacks.js +254 -0
- package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportMenuFactories.js +538 -0
- package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportMenuFingerprints.js +93 -0
- package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportMenuFlow.js +344 -0
- package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportMenuShell.js +65 -0
- package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportMenuState.js +408 -0
- package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportMenuText.js +216 -0
- package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportMessageFlow.js +452 -0
- package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportOutputActions.js +189 -0
- package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportPartnerActions.js +286 -0
- package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportPayloadState.js +108 -0
- package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportProjectActions.js +463 -0
- package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportProjectEntryActions.js +202 -0
- package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportProjectEvents.js +99 -0
- package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportProjectMenus.js +138 -0
- package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportProjectState.js +308 -0
- package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportProjectView.js +426 -0
- package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportRequestFlow.js +278 -0
- package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportSessionActions.js +143 -0
- package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportTerminalActions.js +665 -0
- package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportTerminalRuntime.js +226 -0
- package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportTypes.js +2 -0
- package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportUtils.js +330 -0
- package/dist/services/features/telegram-mcp/src/shared/integrations/telegram/transportXchangeState.js +107 -0
- package/dist/services/features/telegram-mcp/src/shared/integrations/terminal/client.js +255 -0
- package/dist/services/features/telegram-mcp/src/shared/integrations/terminal/ptyRegistry.js +543 -0
- package/dist/services/features/telegram-mcp/src/shared/integrations/xchange/sqliteRecordStore.js +223 -0
- package/dist/services/features/telegram-mcp/src/shared/lib/gatewayScope.js +24 -0
- package/dist/services/features/telegram-mcp/src/shared/lib/logger/logger.js +6 -0
- package/dist/services/features/telegram-mcp/src/shared/lib/project-identity/projectIdentity.js +147 -76
- package/dist/services/features/telegram-mcp/src/shared/lib/telegramXchangeRecords.js +72 -0
- package/dist/services/features/telegram-mcp/src/shared/lib/terminalPromptDetection.js +409 -0
- package/dist/services/features/telegram-mcp/src/shared/lib/version/versionHandshake.js +129 -1
- package/dist/services/features/telegram-mcp/src/shared/lib/xchangeRecordHints.js +98 -0
- package/dist/services/features/telegram-mcp/standalone-http.service.js +12 -0
- package/dist/services/features/telegram-mcp/terminal-buffer.service.js +42 -0
- package/dist/services/features/telegram-mcp/terminal-input.service.js +41 -0
- package/dist/services/features/telegram-mcp/tools-sync.service.js +15 -1
- package/dist/services/features/telegram-mcp/xchange.service.js +123 -0
- package/docs/STANDALONE-ru.md +172 -0
- package/docs/STANDALONE.md +172 -0
- package/package.json +10 -5
- package/scripts/build-package-artifact.sh +27 -0
- package/scripts/deploy-gateway.sh +64 -0
- package/scripts/deploy-onebot-branch.sh +27 -0
- package/scripts/postinstall.js +11 -36
- package/STANDALONE-ru.md +0 -274
- package/STANDALONE.md +0 -274
- package/dist/services/features/telegram-mcp/inbox.service.js +0 -33
- package/dist/services/features/telegram-mcp/pair.service.js +0 -33
- package/dist/services/features/telegram-mcp/src/app/webapp/tmux.js +0 -10
- package/dist/services/features/telegram-mcp/src/features/inbox/model/deleteTelegramInboxMessageTool.js +0 -33
- package/dist/services/features/telegram-mcp/src/features/inbox/model/getTelegramInboxCountTool.js +0 -33
- package/dist/services/features/telegram-mcp/src/features/inbox/model/getTelegramInboxTool.js +0 -33
- package/dist/services/features/telegram-mcp/src/features/inbox/model/inboxService.js +0 -77
- package/dist/services/features/telegram-mcp/src/features/pair-session/model/clearSessionPairingTool.js +0 -33
- package/dist/services/features/telegram-mcp/src/features/pair-session/model/createSessionPairCodeTool.js +0 -33
- package/dist/services/features/telegram-mcp/src/features/pair-session/model/generatePairCode.js +0 -202
- package/dist/services/features/telegram-mcp/src/features/session-context/model/getTmuxTargetTool.js +0 -33
- package/dist/services/features/telegram-mcp/src/features/session-context/model/setTmuxTargetTool.js +0 -33
- package/dist/services/features/telegram-mcp/src/shared/integrations/tmux/client.js +0 -363
package/README-ru.md
CHANGED
|
@@ -1,521 +1,371 @@
|
|
|
1
|
-
|
|
1
|
+
<div align="center">
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
# TellyMCP
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
[](https://www.npmjs.com/package/@deadragdoll/tellymcp)
|
|
7
|
-
[](https://nodejs.org/)
|
|
8
|
-
[](LICENSE)
|
|
5
|
+
**Telegram control plane для MCP-подключённых coding agents**
|
|
9
6
|
|
|
10
|
-
|
|
7
|
+
[English](./README.md) · [Русский](./README-ru.md) · [Standalone](./docs/STANDALONE.md) · [Standalone RU](./docs/STANDALONE-ru.md)
|
|
11
8
|
|
|
12
|
-
|
|
9
|
+
[](https://www.npmjs.com/package/@deadragdoll/tellymcp)
|
|
10
|
+
[](https://nodejs.org/)
|
|
11
|
+
[](./LICENSE)
|
|
12
|
+
[](./README-ru.md#текущая-модель)
|
|
13
|
+
[](./README-ru.md#webhook)
|
|
13
14
|
|
|
14
|
-
|
|
15
|
+
</div>
|
|
15
16
|
|
|
16
|
-
|
|
17
|
+
`@deadragdoll/tellymcp` — Telegram control plane для MCP-подключённых coding agents.
|
|
17
18
|
|
|
18
|
-
|
|
19
|
+
Текущая модель — gateway-first:
|
|
19
20
|
|
|
20
|
-
-
|
|
21
|
-
-
|
|
22
|
-
-
|
|
23
|
-
-
|
|
21
|
+
- один gateway держит Telegram-бота, web app, проекты и live registry консолей
|
|
22
|
+
- один или несколько agent-процессов подключаются к этому gateway
|
|
23
|
+
- каждая запущенная консоль агента — отдельный routable target
|
|
24
|
+
- пользователь работает через gateway-бота, а не через pairing отдельных сессий
|
|
24
25
|
|
|
25
|
-
|
|
26
|
+
## Что умеет
|
|
26
27
|
|
|
27
|
-
-
|
|
28
|
-
-
|
|
29
|
-
-
|
|
30
|
-
-
|
|
31
|
-
-
|
|
28
|
+
- даёт MCP tools для human-in-the-loop через Telegram
|
|
29
|
+
- позволяет одной консоли агента ставить задачу другой консоли
|
|
30
|
+
- хранит structured xchange records в `.mcp-xchange`
|
|
31
|
+
- поддерживает browser automation через Playwright
|
|
32
|
+
- отдаёт Telegram Mini App / Live View с gateway
|
|
33
|
+
- поддерживает polling и webhook на gateway
|
|
34
|
+
- поставляет встроенный Codex plugin со skills под типовые workflow
|
|
32
35
|
|
|
33
|
-
##
|
|
36
|
+
## Текущая модель
|
|
34
37
|
|
|
35
|
-
|
|
36
|
-
- `Collab`-сценарии для локальных и удалённых agent-сессий
|
|
37
|
-
- `.mcp-xchange` как workspace-level handoff шина для note, файлов и скриншотов
|
|
38
|
-
- MCP-native pairing сессий и session-scoped tools
|
|
39
|
-
- optional gateway mode для multi-machine и multi-bot проектов
|
|
38
|
+
Схема:
|
|
40
39
|
|
|
41
|
-
|
|
40
|
+
```text
|
|
41
|
+
Telegram user
|
|
42
|
+
|
|
|
43
|
+
Telegram bot + WebApp
|
|
44
|
+
|
|
|
45
|
+
Gateway
|
|
46
|
+
|
|
|
47
|
+
+-- Agent console A
|
|
48
|
+
+-- Agent console B
|
|
49
|
+
+-- Agent console C
|
|
50
|
+
```
|
|
42
51
|
|
|
43
|
-
|
|
52
|
+
Следствия:
|
|
44
53
|
|
|
45
|
-
-
|
|
46
|
-
-
|
|
47
|
-
-
|
|
54
|
+
- обычный flow больше не использует pairing
|
|
55
|
+
- `/menu` в gateway-боте показывает live-консоли напрямую
|
|
56
|
+
- межсессионная маршрутизация идёт по canonical `session_id = client_uuid:local_session_id`
|
|
57
|
+
- несвязанные задачи читаются через structured xchange records, а не через старые inbox APIs
|
|
48
58
|
|
|
49
|
-
##
|
|
59
|
+
## Основные поверхности
|
|
50
60
|
|
|
51
|
-
|
|
52
|
-
- он понимает локальные и удалённые collaboration targets
|
|
53
|
-
- у него есть live terminal surface, а не только обмен сообщениями
|
|
54
|
-
- он передаёт файлы через workspace-aware exchange paths, а не просто через ad hoc upload
|
|
55
|
-
- он может работать как standalone node или как gateway-backed control plane
|
|
61
|
+
Для человека:
|
|
56
62
|
|
|
57
|
-
|
|
63
|
+
- `telegram_message`
|
|
64
|
+
- `notify_telegram`
|
|
65
|
+
- `browser_screenshot(send_to_telegram=true)`
|
|
58
66
|
|
|
59
|
-
-
|
|
60
|
-
- запускать рядом разных агентов, если каждый умеет подключаться по MCP
|
|
61
|
-
- подруливать tmux-сессией без ноутбука
|
|
62
|
-
- маршрутизировать работу между `frontend`, `backend`, `review` и другими локальными сессиями
|
|
63
|
-
- работать с удалёнными сессиями через gateway-backed project
|
|
64
|
-
- передавать note, скриншоты и реальные файлы через `.mcp-xchange`
|
|
65
|
-
- проверять локальный веб-интерфейс через `browser_*` tools и отправлять результат обратно в Telegram
|
|
67
|
+
Для agent-to-agent:
|
|
66
68
|
|
|
67
|
-
|
|
69
|
+
- `partner_note`
|
|
70
|
+
- `send_partner_note`
|
|
71
|
+
- `send_partner_file`
|
|
72
|
+
- `list_gateway_sessions`
|
|
68
73
|
|
|
69
|
-
|
|
70
|
-
- Telegram ask/notify/inbox
|
|
71
|
-
- `Live` tmux control
|
|
72
|
-
- browser inspection и screenshots
|
|
73
|
-
- partner notes и partner files
|
|
74
|
-
- tools sync и version checks
|
|
74
|
+
Для браузера:
|
|
75
75
|
|
|
76
|
-
|
|
76
|
+
- `browser_open`
|
|
77
|
+
- `browser_click`
|
|
78
|
+
- `browser_fill`
|
|
79
|
+
- `browser_press`
|
|
80
|
+
- `browser_wait_for`
|
|
81
|
+
- `browser_screenshot`
|
|
77
82
|
|
|
78
|
-
|
|
79
|
-
- target-сессии отправляется только результат
|
|
80
|
-
- исходное поручение не должно пересылаться дальше как новая задача
|
|
83
|
+
Синхронизация инструкций:
|
|
81
84
|
|
|
82
|
-
|
|
85
|
+
- `refresh_tools_markdown`
|
|
86
|
+
- `.mcpsession.json` хранит startup identity и последний известный tools hash
|
|
83
87
|
|
|
84
|
-
##
|
|
88
|
+
## Требования
|
|
85
89
|
|
|
86
|
-
- Node.js 24
|
|
87
|
-
- `tmux`
|
|
90
|
+
- Node.js `>= 24`
|
|
88
91
|
- Redis
|
|
89
|
-
-
|
|
90
|
-
- для
|
|
91
|
-
-
|
|
92
|
-
|
|
93
|
-
## `tmux` настоятельно рекомендуется
|
|
94
|
-
|
|
95
|
-
TellyMCP лучше всего работает, когда сам агент запущен внутри `tmux`.
|
|
92
|
+
- PostgreSQL для gateway mode
|
|
93
|
+
- опционально RabbitMQ для durable gateway fanout
|
|
94
|
+
- Playwright browser binaries, если нужны browser tools
|
|
96
95
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
- не будет `Live View`
|
|
100
|
-
- не будет tmux `nudge`
|
|
101
|
-
- не будет прямого управления tmux из Telegram Mini App
|
|
102
|
-
|
|
103
|
-
Типичный старт:
|
|
96
|
+
## Установка
|
|
104
97
|
|
|
105
98
|
```bash
|
|
106
|
-
|
|
99
|
+
npm install -g @deadragdoll/tellymcp
|
|
107
100
|
```
|
|
108
101
|
|
|
109
|
-
|
|
102
|
+
Если нужны browser tools:
|
|
110
103
|
|
|
111
104
|
```bash
|
|
112
|
-
|
|
105
|
+
tellymcp browser install
|
|
113
106
|
```
|
|
114
107
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
- по нему проще различать агентов
|
|
118
|
-
- оно участвует в tmux-related UI и диагностике
|
|
119
|
-
- с ним проще понимать, какую сессию ты открываешь в Telegram и `Live`
|
|
120
|
-
|
|
121
|
-
Лучше использовать короткие осмысленные имена:
|
|
122
|
-
|
|
123
|
-
- `backend`
|
|
124
|
-
- `frontend`
|
|
125
|
-
- `review`
|
|
126
|
-
- `ops`
|
|
127
|
-
|
|
128
|
-
Если агентов несколько, лучше запускать каждого в своей tmux-сессии или pane и привязывать отдельно.
|
|
108
|
+
Если используешь Codex:
|
|
129
109
|
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
110
|
+
```bash
|
|
111
|
+
tellymcp codex-plugin install
|
|
112
|
+
```
|
|
133
113
|
|
|
134
114
|
## Быстрый старт
|
|
135
115
|
|
|
136
|
-
### 1.
|
|
137
|
-
|
|
138
|
-
Это самый простой режим:
|
|
116
|
+
### 1. Gateway
|
|
139
117
|
|
|
140
|
-
|
|
141
|
-
- без Postgres
|
|
142
|
-
- без RabbitMQ
|
|
143
|
-
|
|
144
|
-
Установка:
|
|
118
|
+
Создай workspace и env:
|
|
145
119
|
|
|
146
120
|
```bash
|
|
147
|
-
|
|
121
|
+
mkdir -p ~/telly-gateway
|
|
122
|
+
cd ~/telly-gateway
|
|
123
|
+
tellymcp init gateway
|
|
148
124
|
```
|
|
149
125
|
|
|
150
|
-
|
|
126
|
+
Или возьми sample:
|
|
151
127
|
|
|
152
|
-
|
|
153
|
-
tellymcp init client
|
|
154
|
-
```
|
|
128
|
+
- [.env.example.gateway](./.env.example.gateway)
|
|
155
129
|
|
|
156
|
-
|
|
130
|
+
Минимально важные значения:
|
|
157
131
|
|
|
158
132
|
- `TELEGRAM_BOT_TOKEN`
|
|
159
|
-
- `TELEGRAM_BOT_USERNAME`
|
|
160
133
|
- `REDIS_HOST`
|
|
161
|
-
- `
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
134
|
+
- `DB_HOST`
|
|
135
|
+
- `DB_USER`
|
|
136
|
+
- `DB_PASSWORD`
|
|
137
|
+
- `DB_NAME`
|
|
138
|
+
- `GATEWAY_PUBLIC_URL`
|
|
139
|
+
- `GATEWAY_WS_URL`
|
|
140
|
+
- `GATEWAY_TOKEN`
|
|
168
141
|
|
|
169
|
-
|
|
142
|
+
Запуск:
|
|
170
143
|
|
|
171
144
|
```bash
|
|
172
145
|
tellymcp run --env .env
|
|
173
146
|
```
|
|
174
147
|
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
- `http://127.0.0.1:8787/mcp`
|
|
178
|
-
|
|
179
|
-
Чтобы получить готовый JSON snippet для агента:
|
|
180
|
-
|
|
181
|
-
```bash
|
|
182
|
-
tellymcp mcp --help
|
|
183
|
-
```
|
|
184
|
-
|
|
185
|
-
### 2. Gateway или combined `both`
|
|
186
|
-
|
|
187
|
-
Используй этот режим, если нужен:
|
|
188
|
-
|
|
189
|
-
- `Collab` между машинами
|
|
190
|
-
- проекты между разными ботами
|
|
191
|
-
- gateway-relayed Live View
|
|
192
|
-
- persistent gateway-side состояние по проектам и доставке
|
|
148
|
+
### 2. Agent
|
|
193
149
|
|
|
194
|
-
|
|
150
|
+
Для каждой консоли лучше отдельный workspace:
|
|
195
151
|
|
|
196
152
|
```bash
|
|
197
|
-
|
|
153
|
+
mkdir -p ~/agent-a
|
|
154
|
+
cd ~/agent-a
|
|
155
|
+
tellymcp init client
|
|
198
156
|
```
|
|
199
157
|
|
|
200
|
-
|
|
158
|
+
Или используй sample:
|
|
201
159
|
|
|
202
|
-
|
|
203
|
-
tellymcp init both
|
|
204
|
-
```
|
|
160
|
+
- [.env.example.client](./.env.example.client)
|
|
205
161
|
|
|
206
|
-
|
|
162
|
+
Минимально важные значения:
|
|
207
163
|
|
|
208
|
-
- `DISTRIBUTED_MODE=gateway|both`
|
|
209
|
-
- `PORT`
|
|
210
|
-
- `ROOT_PREFIX=/api`
|
|
211
|
-
- `TELEGRAM_BOT_TOKEN`
|
|
212
|
-
- `REDIS_*`
|
|
213
|
-
- `DB_*`
|
|
214
|
-
- `WEBAPP_PUBLIC_URL`
|
|
215
164
|
- `GATEWAY_PUBLIC_URL`
|
|
216
165
|
- `GATEWAY_WS_URL`
|
|
217
|
-
-
|
|
166
|
+
- `GATEWAY_TOKEN`
|
|
167
|
+
- `GATEWAY_USER_UUID`, если консоль должна быть видна конкретному владельцу в gateway-боте
|
|
218
168
|
|
|
219
|
-
|
|
169
|
+
Рекомендуется:
|
|
220
170
|
|
|
221
|
-
-
|
|
222
|
-
-
|
|
223
|
-
- `/api/gateway`
|
|
224
|
-
- `/api/healthz`
|
|
171
|
+
- по умолчанию используется встроенный PTY terminal runtime
|
|
172
|
+
- на первом запуске явно задать `TELLYMCP_SESSION_ID` и `TELLYMCP_SESSION_LABEL`
|
|
225
173
|
|
|
226
|
-
|
|
174
|
+
Первый запуск:
|
|
227
175
|
|
|
228
176
|
```bash
|
|
229
|
-
tellymcp
|
|
177
|
+
tellymcp run --env .env -s NEW
|
|
230
178
|
```
|
|
231
179
|
|
|
232
|
-
|
|
180
|
+
После первого запуска `.mcpsession.json` хранит:
|
|
233
181
|
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
Типовой публичный MCP endpoint:
|
|
182
|
+
- `local_session_id`
|
|
183
|
+
- `session_label`
|
|
184
|
+
- `env_file`
|
|
239
185
|
|
|
240
|
-
|
|
186
|
+
Поэтому дальше в том же каталоге обычно достаточно:
|
|
241
187
|
|
|
242
|
-
|
|
188
|
+
```bash
|
|
189
|
+
tellymcp run
|
|
190
|
+
```
|
|
243
191
|
|
|
244
|
-
|
|
192
|
+
## Webhook
|
|
245
193
|
|
|
246
|
-
|
|
194
|
+
Gateway умеет работать через Telegram webhook.
|
|
247
195
|
|
|
248
|
-
|
|
249
|
-
- в `client`-режиме тоже может открываться через общий gateway domain
|
|
250
|
-
- показывает видимую область tmux pane и отправляет ограниченный набор control actions
|
|
251
|
-
- валидирует Telegram `initData` на сервере
|
|
252
|
-
- умеет открываться в режимах:
|
|
253
|
-
- `default`
|
|
254
|
-
- `expand`
|
|
255
|
-
- `fullscreen` с fallback на `expand`
|
|
256
|
-
- после успешного bootstrap удаляет временное launcher-сообщение
|
|
257
|
-
- автоматически восстанавливается после короткого рестарта шлюза:
|
|
258
|
-
- краткий `502/503` переживается обычным polling
|
|
259
|
-
- если in-process WebApp session на шлюзе была потеряна и приходит `401/403`, Mini App сама делает повторный bootstrap
|
|
260
|
-
- в типовом restart-case переоткрывать `Live` не нужно
|
|
196
|
+
Если nginx уже проксирует весь `/api/` на standalone HTTP listener gateway, отдельный `location` для webhook не обязателен. Route такой:
|
|
261
197
|
|
|
262
|
-
|
|
198
|
+
- `/api/telegram/webhook`
|
|
263
199
|
|
|
264
|
-
|
|
200
|
+
Нужные env:
|
|
265
201
|
|
|
266
|
-
|
|
202
|
+
```env
|
|
203
|
+
TELEGRAM_WEBHOOK_ENABLED=true
|
|
204
|
+
TELEGRAM_WEBHOOK_PATH=/telegram/webhook
|
|
205
|
+
TELEGRAM_WEBHOOK_PUBLIC_URL=https://your-domain.example/api/telegram/webhook
|
|
206
|
+
TELEGRAM_WEBHOOK_SECRET=change_me_webhook_secret
|
|
207
|
+
```
|
|
267
208
|
|
|
268
|
-
|
|
209
|
+
Когда webhook mode включён:
|
|
269
210
|
|
|
270
|
-
-
|
|
271
|
-
-
|
|
272
|
-
-
|
|
273
|
-
- не для `both`
|
|
211
|
+
- gateway вызывает `setWebhook(...)` на старте
|
|
212
|
+
- polling не запускается
|
|
213
|
+
- секрет проверяется через `x-telegram-bot-api-secret-token`
|
|
274
214
|
|
|
275
|
-
|
|
215
|
+
## MCP
|
|
276
216
|
|
|
277
|
-
|
|
278
|
-
- `postgres` для `gateway` / `both`
|
|
279
|
-
- `rabbitmq` только если нужен durable fanout на шлюзе
|
|
217
|
+
### Local HTTP
|
|
280
218
|
|
|
281
|
-
|
|
219
|
+
В client mode локальный MCP endpoint обычно:
|
|
282
220
|
|
|
283
|
-
```
|
|
284
|
-
|
|
285
|
-
```
|
|
286
|
-
|
|
287
|
-
Redis + Postgres, для `gateway` или `both`:
|
|
288
|
-
|
|
289
|
-
```bash
|
|
290
|
-
docker compose --profile gateway up -d
|
|
221
|
+
```text
|
|
222
|
+
http://127.0.0.1:8787/mcp
|
|
291
223
|
```
|
|
292
224
|
|
|
293
|
-
|
|
225
|
+
Helper:
|
|
294
226
|
|
|
295
227
|
```bash
|
|
296
|
-
|
|
228
|
+
tellymcp mcp --url http://127.0.0.1:8787/mcp
|
|
297
229
|
```
|
|
298
230
|
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
1. Скопировать пример:
|
|
231
|
+
Для Codex и похожих агентов используй MCP HTTP endpoint, который поднимает `tellymcp run`.
|
|
302
232
|
|
|
303
|
-
|
|
304
|
-
cp .env.example.gateway .env-gateway
|
|
305
|
-
```
|
|
233
|
+
## Codex Plugin
|
|
306
234
|
|
|
307
|
-
|
|
235
|
+
Пакет включает локальный Codex plugin со skills для:
|
|
308
236
|
|
|
309
|
-
-
|
|
310
|
-
- `
|
|
311
|
-
-
|
|
312
|
-
-
|
|
313
|
-
- `GATEWAY_WS_URL`
|
|
314
|
-
- `MCP_HTTP_BEARER_TOKEN`
|
|
237
|
+
- ответов человеку в Telegram
|
|
238
|
+
- `partner_note`
|
|
239
|
+
- browser screenshot задач
|
|
240
|
+
- artifact-return flow
|
|
315
241
|
|
|
316
|
-
|
|
242
|
+
Команды:
|
|
317
243
|
|
|
318
244
|
```bash
|
|
319
|
-
|
|
245
|
+
tellymcp codex-plugin status
|
|
246
|
+
tellymcp codex-plugin install
|
|
320
247
|
```
|
|
321
248
|
|
|
322
|
-
|
|
249
|
+
Installer:
|
|
323
250
|
|
|
324
|
-
-
|
|
325
|
-
-
|
|
326
|
-
-
|
|
251
|
+
- копирует bundled plugin в managed local Codex path
|
|
252
|
+
- обновляет personal marketplace manifest
|
|
253
|
+
- ставит или обновляет plugin, если найден Codex CLI
|
|
327
254
|
|
|
328
|
-
|
|
255
|
+
## Browser Workflow
|
|
329
256
|
|
|
330
|
-
|
|
331
|
-
- `REDIS_HOST=redis`
|
|
332
|
-
- `DB_HOST=postgres`
|
|
257
|
+
Browser tools используют Playwright Chromium.
|
|
333
258
|
|
|
334
|
-
|
|
259
|
+
Предпочтительный путь:
|
|
335
260
|
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
- `
|
|
261
|
+
1. `browser_open`
|
|
262
|
+
2. `browser_screenshot`
|
|
263
|
+
3. дальше либо:
|
|
264
|
+
- `send_to_telegram=true` для ответа человеку
|
|
265
|
+
- `send_partner_file` для возврата артефакта другой консоли
|
|
340
266
|
|
|
341
|
-
|
|
267
|
+
Если browser runtime не установлен:
|
|
342
268
|
|
|
343
269
|
```bash
|
|
344
|
-
|
|
270
|
+
tellymcp browser install
|
|
345
271
|
```
|
|
346
272
|
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
```bash
|
|
350
|
-
tellymcp run --env .env
|
|
351
|
-
```
|
|
352
|
-
|
|
353
|
-
Для `client` и `both` по-прежнему рекомендуется именно хостовый запуск.
|
|
354
|
-
|
|
355
|
-
## Как начать работу с ботом изнутри агента
|
|
356
|
-
|
|
357
|
-
После подключения MCP можно просто написать агенту обычной фразой, что нужно привязаться к Telegram.
|
|
358
|
-
|
|
359
|
-
Типовые фразы, которые агент должен понимать:
|
|
360
|
-
|
|
361
|
-
- `привяжись к Telegram`
|
|
362
|
-
- `подключись к Telegram`
|
|
363
|
-
- `зарегистрируй эту сессию в Telegram`
|
|
364
|
-
- `свяжи эту сессию с ботом`
|
|
365
|
-
- `создай код привязки к Telegram`
|
|
366
|
-
- `дай код для pairing с Telegram`
|
|
273
|
+
Не подменяй browser workflow ad hoc shell-командами с Playwright, кроме случаев, когда ты отлаживаешь сам browser runtime.
|
|
367
274
|
|
|
368
|
-
|
|
275
|
+
## Terminal Blockers
|
|
369
276
|
|
|
370
|
-
|
|
371
|
-
2. Возвращается короткий код и, если возможно, deep link.
|
|
372
|
-
3. Ты открываешь Telegram и отправляешь боту `/start <code>` или `/link <code>`.
|
|
373
|
-
4. После успешной привязки можно открыть `/menu`.
|
|
277
|
+
Gateway prompt scanner теперь живёт от live-client lifecycle:
|
|
374
278
|
|
|
375
|
-
|
|
279
|
+
- на старте gateway scanner только armed, но не крутится вхолостую
|
|
280
|
+
- реальная работа начинается после подключения live client
|
|
281
|
+
- relay console materialization идёт из `hello` и owner-route hydration, а не из `/menu`
|
|
282
|
+
- детект работает по хвосту захваченного terminal buffer
|
|
376
283
|
|
|
377
|
-
|
|
378
|
-
Привяжись к Telegram и дай мне код для pairing.
|
|
379
|
-
```
|
|
284
|
+
Основная эвристика blocker-а:
|
|
380
285
|
|
|
381
|
-
|
|
286
|
+
- подряд идущие numbered choices: `1.`, `2.`, `3.`
|
|
287
|
+
- рядом есть action hints вроде `press`, `input`, `choose`, `enter`, `esc`, `yes`, `no`
|
|
288
|
+
- в Telegram notice попадают и 1-2 строки контекста выше menu block
|
|
382
289
|
|
|
383
|
-
|
|
290
|
+
Когда blocker найден, gateway может отправить inline-кнопки:
|
|
384
291
|
|
|
385
|
-
1
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
4. Укажи `TELEGRAM_BOT_USERNAME`, если хочешь deep-link подсказки для pairing.
|
|
292
|
+
- `1..N`
|
|
293
|
+
- `Enter`
|
|
294
|
+
- `Esc`
|
|
389
295
|
|
|
390
|
-
|
|
296
|
+
Эти кнопки отправляют в консоль ровно цифру или terminal action. Навигация маркером не используется.
|
|
391
297
|
|
|
392
|
-
|
|
298
|
+
Операционные заметки:
|
|
393
299
|
|
|
394
|
-
|
|
300
|
+
- одинаковый blocker fingerprint не перевысылается повторно
|
|
301
|
+
- relay capture miss для offline agent считается debug-only шумом
|
|
302
|
+
- `Storage` и `Screenshots` на gateway теперь relay-aware и читают metadata через gateway routes, а не через filesystem самого gateway
|
|
395
303
|
|
|
396
|
-
|
|
397
|
-
tellymcp mcp --help
|
|
398
|
-
```
|
|
304
|
+
## Collaboration
|
|
399
305
|
|
|
400
|
-
|
|
306
|
+
Проекты:
|
|
401
307
|
|
|
402
|
-
-
|
|
403
|
-
-
|
|
404
|
-
-
|
|
308
|
+
- live presence консолей идёт из gateway live registry
|
|
309
|
+
- membership проекта хранится отдельно от live presence
|
|
310
|
+
- один client может иметь несколько live консолей одновременно
|
|
311
|
+
- console participation в проекте хранится отдельно
|
|
405
312
|
|
|
406
|
-
|
|
313
|
+
Ожидаемое поведение агента:
|
|
407
314
|
|
|
408
|
-
`
|
|
315
|
+
- target резолвится через `list_gateway_sessions`
|
|
316
|
+
- входящая работа читается через `list_xchange_records` и `get_xchange_record`
|
|
317
|
+
- реальные файлы возвращаются через `send_partner_file`
|
|
318
|
+
- `mark_xchange_record_read` вызывается только после успешного outbound reply
|
|
409
319
|
|
|
410
|
-
|
|
320
|
+
## Файлы конфигурации
|
|
411
321
|
|
|
412
|
-
|
|
413
|
-
- `.env`
|
|
414
|
-
- Redis
|
|
415
|
-
- локальный MCP bind
|
|
416
|
-
- внешний `gateway healthz`, если задан `GATEWAY_PUBLIC_URL`
|
|
417
|
-
- `GATEWAY_WS_URL`
|
|
418
|
-
- `WEBAPP_PUBLIC_URL`
|
|
322
|
+
Канонические стартовые точки:
|
|
419
323
|
|
|
420
|
-
|
|
324
|
+
- [.env.example.gateway](./.env.example.gateway)
|
|
325
|
+
- [.env.example.client](./.env.example.client)
|
|
421
326
|
|
|
422
|
-
|
|
423
|
-
- `.env`
|
|
424
|
-
- Redis
|
|
425
|
-
- локальный `healthz`
|
|
426
|
-
- публичный `healthz`
|
|
427
|
-
- публичный `ws`
|
|
428
|
-
- публичный `webapp`
|
|
429
|
-
- Postgres
|
|
430
|
-
- RabbitMQ, если настроен
|
|
327
|
+
Bundled templates:
|
|
431
328
|
|
|
432
|
-
|
|
329
|
+
- [config/templates/env.gateway.template](./config/templates/env.gateway.template)
|
|
330
|
+
- [config/templates/env.client.template](./config/templates/env.client.template)
|
|
331
|
+
- [config/templates/env.both.template](./config/templates/env.both.template)
|
|
433
332
|
|
|
434
|
-
|
|
333
|
+
Samples уже вычищены под текущий runtime:
|
|
435
334
|
|
|
436
|
-
-
|
|
437
|
-
-
|
|
438
|
-
- `
|
|
439
|
-
- `
|
|
440
|
-
- `REDIS_DB`
|
|
441
|
-
- `MODE=queue|reject`
|
|
442
|
-
- `PAIR_CODE_TTL_SECONDS`
|
|
443
|
-
- `MCP_HTTP_HOST`
|
|
444
|
-
- `MCP_HTTP_PORT`
|
|
445
|
-
- `MCP_HTTP_PATH`
|
|
446
|
-
- `MCP_HTTP_BEARER_TOKEN`
|
|
447
|
-
- `TMUX_SOCKET_PATH`
|
|
448
|
-
- `TMUX_NUDGE_ENABLED`
|
|
449
|
-
- `TMUX_NUDGE_DEBOUNCE_SECONDS`
|
|
450
|
-
- `TMUX_NUDGE_COOLDOWN_SECONDS`
|
|
451
|
-
- `WEBAPP_ENABLED`
|
|
452
|
-
- `WEBAPP_BASE_PATH`
|
|
453
|
-
- `WEBAPP_LAUNCH_MODE=default|expand|fullscreen`
|
|
454
|
-
- `MCP_XCHANGE_DIR`
|
|
455
|
-
- `PROXY_USE=http|socks5`
|
|
456
|
-
- `HTTP_PROXY`
|
|
457
|
-
- `SOCKS5_PROXY`
|
|
458
|
-
- `LOG_LEVEL`
|
|
459
|
-
- `LOG_FILE_ENABLED`
|
|
460
|
-
- `LOG_FILE_PATH`
|
|
461
|
-
|
|
462
|
-
Только client:
|
|
463
|
-
|
|
464
|
-
- `DISTRIBUTED_MODE=client`
|
|
465
|
-
- `GATEWAY_PUBLIC_URL`
|
|
466
|
-
- `GATEWAY_WS_URL`
|
|
467
|
-
- `GATEWAY_WS_PATH`
|
|
468
|
-
- `GATEWAY_AUTH_TOKEN`
|
|
469
|
-
|
|
470
|
-
Gateway / both:
|
|
335
|
+
- убраны старые inbox-only настройки
|
|
336
|
+
- убраны obsolete pairing-oriented тексты
|
|
337
|
+
- убраны неиспользуемые секреты вроде `SESSION_SECRET`
|
|
338
|
+
- убран неиспользуемый `APP_NAME`
|
|
471
339
|
|
|
472
|
-
|
|
473
|
-
- `PORT`
|
|
474
|
-
- `ROOT_PREFIX=/api`
|
|
475
|
-
- `DB_HOST`
|
|
476
|
-
- `DB_PORT`
|
|
477
|
-
- `DB_USER`
|
|
478
|
-
- `DB_PASSWORD`
|
|
479
|
-
- `DB_NAME`
|
|
480
|
-
- `RMQ_HOST`
|
|
481
|
-
- `RMQ_PORT`
|
|
482
|
-
- `RMQ_USER`
|
|
483
|
-
- `RMQ_PASSWORD`
|
|
484
|
-
- `RMQ_VHOST`
|
|
485
|
-
- `RMQ_EXCHANGE`
|
|
340
|
+
## Операционные команды
|
|
486
341
|
|
|
487
|
-
|
|
342
|
+
Проверка окружения:
|
|
488
343
|
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
344
|
+
```bash
|
|
345
|
+
tellymcp doctor --env .env
|
|
346
|
+
```
|
|
492
347
|
|
|
493
|
-
|
|
348
|
+
Разрушительная очистка local+gateway state:
|
|
494
349
|
|
|
495
|
-
|
|
350
|
+
```bash
|
|
351
|
+
tellymcp system-prune --env .env --yes
|
|
352
|
+
```
|
|
496
353
|
|
|
497
|
-
|
|
498
|
-
2. Агент вызывает `create_session_pair_code`.
|
|
499
|
-
3. Человек делает `/start <code>` или `/link <code>` в Telegram.
|
|
500
|
-
4. После pairing бот открывает меню сессий, inbox, storage, local/collab и live view.
|
|
501
|
-
5. Агент вызывает `ask_user_telegram` для связанной `session_id`.
|
|
502
|
-
6. Ответ пользователя возвращается как MCP tool output.
|
|
503
|
-
7. Несвязанные входящие Telegram-сообщения остаются в inbox этой сессии.
|
|
504
|
-
8. Файлы и note попадают в `.mcp-xchange`.
|
|
354
|
+
## Карта документации
|
|
505
355
|
|
|
506
|
-
|
|
356
|
+
- [README.md](./README.md)
|
|
357
|
+
- [STANDALONE.md](./docs/STANDALONE.md)
|
|
358
|
+
- [STANDALONE-ru.md](./docs/STANDALONE-ru.md)
|
|
359
|
+
- [TOOLS.md](./TOOLS.md)
|
|
360
|
+
- [screenshots/README.md](./screenshots/README.md)
|
|
507
361
|
|
|
508
|
-
|
|
509
|
-
tellymcp help
|
|
510
|
-
tellymcp doctor --env .env
|
|
511
|
-
tellymcp mcp --help
|
|
512
|
-
tellymcp run --env .env
|
|
513
|
-
```
|
|
362
|
+
## Статус
|
|
514
363
|
|
|
515
|
-
|
|
364
|
+
Этот README описывает текущую gateway-first модель.
|
|
516
365
|
|
|
517
|
-
|
|
366
|
+
Legacy concepts, которые не стоит использовать в новых setup:
|
|
518
367
|
|
|
519
|
-
-
|
|
520
|
-
-
|
|
521
|
-
-
|
|
368
|
+
- pairing codes
|
|
369
|
+
- session inbox APIs
|
|
370
|
+
- `Local` partner menu
|
|
371
|
+
- linked-session flows вне `partner_note` / project collaboration
|