|
23 | 23 | ## 3. Project Topology |
24 | 24 |
|
25 | 25 | - `/index.ts`: Main extension entrypoint and runtime composition layer for the bridge |
26 | | -- `/lib/*.ts`: Flat domain modules for reusable runtime logic. Favor domain files such as queueing/runtime, replies, polling, updates, attachments, registration/hooks, pi SDK adapter, Telegram API, config, turns, media, setup, rendering, menu/status/model-resolution support, and other cohesive bridge subsystems; use `shared` only when a type or constant truly spans multiple domains |
| 26 | +- `/lib/*.ts`: Flat domain modules for reusable runtime logic. Favor domain files such as queueing/runtime, replies, polling, updates, attachments, commands, lifecycle hooks, prompts, pi SDK adapter, Telegram API, config, turns, media, setup, rendering, menu/status/model-resolution support, and other cohesive bridge subsystems; use `shared` only when a type or constant truly spans multiple domains |
27 | 27 | - `/tests/*.test.ts`: Domain-mirrored regression suites that follow the same flat naming as `/lib` |
28 | 28 | - `/docs/README.md`: Documentation index for technical project docs |
29 | 29 | - `/docs/architecture.md`: Runtime and subsystem overview for the bridge |
|
86 | 86 | - Keep comments and user-facing docs in English unless the surrounding file already follows another convention |
87 | 87 | - Each project `.ts` file should start with a short multi-line responsibility header comment that explains the file boundary to future maintainers |
88 | 88 | - Name extracted `/lib` modules and mirrored `/tests` suites by bare domain when the repository already supplies the Telegram scope; prefer `api.ts`, `queue.ts`, `updates.ts`, and `queue.test.ts` over redundant `telegram-*` filename prefixes |
| 89 | +- Keep test helpers with the mirrored domain suite by default because test files mirror module-domain boundaries; introduce shared `tests/fixtures` only when multiple domain suites truly reuse the same setup |
89 | 90 | - Prefer targeted edits, keeping `index.ts` as the orchestration layer and moving reusable logic into flat `/lib` domain modules when a subsystem becomes large enough to earn extraction |
90 | 91 | - Keep composition wiring DRY with small local adapters or owning-domain contracts when repetition appears, but do not hide live mutable session state behind broad facades just to reduce repeated closures |
91 | 92 | - Keep interface contracts consistent for the same runtime entity: prefer the owning domain's exported contract when multiple modules mean the same entity, and use local structural `*Like`/view contracts only for deliberate narrow projections that avoid real coupling without duplicating source-of-truth shapes |
92 | 93 |
|
93 | 94 | ## 6.3 Current Domain Ownership Snapshot |
94 | 95 |
|
95 | | -- Queue owns scheduling/lifecycle semantics: lane contracts, queue and active-turn stores, mutations, dispatch readiness/runtime, control/prompt enqueueing, session state appliers, and agent/tool lifecycle hooks; model owns model identity/thinking-level contracts, scoped resolution and CLI pattern parsing, current-model state/runtime helpers, in-flight switch state, restart eligibility, delayed abort decisions, Telegram-prefix-defaulted continuation prompt construction/queueing, and controller runtime binding over queue turns |
96 | | -- Runtime owns session-local primitives and timers; locks owns shared `locks.json` singleton ownership, interactive takeover, stale same-`cwd` restart resume, session-replacement suspension, and ownership-drift shutdown; pi owns direct SDK imports and bound extension API ports; config owns persisted bot/session pairing state, single-user authorization, first-user pairing side effects, and inbound attachment handler config; API owns Bot API transport shapes/helpers, temp-dir/inbound-limit/runtime-error helpers, and runtime-bound chat actions |
97 | | -- Preview owns streaming preview lifecycle and transports, defaulting reply metadata through the replies-domain helper when callers do not override it; replies owns final rendered-message delivery and reply parameters; rendering owns Telegram HTML Markdown/block/chunk/preview-snapshot formatting |
98 | | -- Polling owns long-poll controller state/activity/loop wiring; updates owns callback/message/edit/reaction classification/execution; routing owns inbound update composition across menus, commands, media grouping, prompt queueing, edits, and paired authorization; handlers owns inbound attachment handler matching, command/tool invocation, prompt-text injection, and fallback behavior; registration owns pi tool/command/lifecycle-hook binding |
99 | | -- Commands own slash-command parsing, execution-mode contracts, command target/control queue adapters, bot-command metadata/registration, and stop/compact/status/model/help side effects |
100 | | -- Menu owns inline menu state/cache/building, callback/action runtimes, status/thinking/model UI support, and selection planning; status owns bridge status rendering, grouped pi-side diagnostic lines, and recent-event state |
101 | | -- Turns own Telegram prompt turn-building/editing, prompt-prefix identity, and attachment-handler output handoff into prompt content; media owns inbound text/file/media-group extraction and download assembly; attachments own outbound file queueing, narrow structural attachment turn targets, stat checks, limits, and delivery classification; setup owns token prompt, env fallback, and validation flow |
| 96 | +The canonical detailed ownership map lives in [`docs/architecture.md`](./docs/architecture.md). Keep this section as a compact agent-facing index, not a second copy of the full map. |
| 97 | + |
| 98 | +- Scheduling and lifecycle: `queue`, `runtime`, `lifecycle`, `locks` |
| 99 | +- Telegram transport and inbound flow: `api`, `polling`, `updates`, `routing`, `media`, `turns`, `handlers`, `config`, `setup` |
| 100 | +- Response surfaces: `preview`, `replies`, `rendering`, `attachments`, `status` |
| 101 | +- Controls and model UI: `commands`, `menu`, `model`, `prompts` |
| 102 | +- Pi SDK boundary: `pi` owns direct pi imports and bound extension API ports |
102 | 103 |
|
103 | 104 | ## 6.4 Entrypoint And Import Boundaries |
104 | 105 |
|
|
126 | 127 | - For `/telegram-setup`, prefer the locally saved bot token over environment variables on repeat setup runs; env vars are the bootstrap path when no local token exists |
127 | 128 | - Status/model/thinking controls are driven through Telegram inline keyboards and callback queries |
128 | 129 | - Inbound files may become pi image inputs or configured attachment-handler text before queueing; outbound files must flow through `telegram_attach` |
| 130 | +- Inbound attachment handlers use command templates as the standard integration contract; do not couple handler execution to another extension's private registry or config format unless pi exposes a public extension-callable `executeTool(name, args)` API |
129 | 131 |
|
130 | 132 | ## 9. Pre-Task Preparation Protocol |
131 | 133 |
|
|
0 commit comments