Skip to content

Commit 10632b9

Browse files
committed
0.5.0: _
1 parent c26621b commit 10632b9

38 files changed

Lines changed: 1477 additions & 1200 deletions

AGENTS.md

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
## 3. Project Topology
2424

2525
- `/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
2727
- `/tests/*.test.ts`: Domain-mirrored regression suites that follow the same flat naming as `/lib`
2828
- `/docs/README.md`: Documentation index for technical project docs
2929
- `/docs/architecture.md`: Runtime and subsystem overview for the bridge
@@ -86,19 +86,20 @@
8686
- Keep comments and user-facing docs in English unless the surrounding file already follows another convention
8787
- Each project `.ts` file should start with a short multi-line responsibility header comment that explains the file boundary to future maintainers
8888
- 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
8990
- 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
9091
- 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
9192
- 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
9293

9394
## 6.3 Current Domain Ownership Snapshot
9495

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
102103

103104
## 6.4 Entrypoint And Import Boundaries
104105

@@ -126,6 +127,7 @@
126127
- 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
127128
- Status/model/thinking controls are driven through Telegram inline keyboards and callback queries
128129
- 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
129131

130132
## 9. Pre-Task Preparation Protocol
131133

BACKLOG.md

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,33 @@
11
# Project Backlog
22

3-
## Active Backlog
3+
## Deferred Candidates
44

5-
_No active backlog items._
5+
No known release-blocking 0.5.0 tasks. The items below are intentionally gated; do not implement them until a reopen trigger makes the scope concrete.
6+
7+
### Compression/Decomposition
8+
9+
- `lib/queue.ts`: first extraction candidate is pure dispatch/session/agent-end planning, but only after a real runtime change, failing validation, or targeted refactor earns the seam.
10+
- `lib/menu.ts`: possible seams are state/cache storage, callback planning/execution, and render-payload/reply-markup builders. Preserve the model-domain boundary.
11+
- `lib/rendering.ts`: possible seams are HTML chunking and stable-preview snapshot derivation. Split only if renderer work becomes active enough to justify new files.
12+
- Runtime-event recorder ports are intentionally structural/local for now because `runtime` must stay free of local imports. Revisit only if category taxonomy or signatures drift.
13+
- `tests/queue.test.ts` and `tests/runtime.test.ts` are large. Keep helpers local to mirrored domain suites; split only alongside real source seams.
14+
15+
### Queue And Control UX
16+
17+
- `/status` and `/model` are immediate Telegram controls. Keep them out of the Telegram queue unless a future pi API constraint requires deferral.
18+
- Model-switch continuation turns may still use the control lane so they resume before normal queued prompts.
19+
- `👍` and `👎` are local Telegram queue operations only: `👍` changes ordering, `👎` removes a waiting turn. Do not map voice, files, images, or reactions to pi `steer` without a separate explicit operator design.
20+
- Pi-side status bar distinguishes active, dispatching, queued, tool-running, model-switch, and compacting states. Reopen copy work only after real operator confusion.
21+
- Prefer local domain-owned formatting helpers; keep Telegram rendering helpers separate from Pi TUI/tool-result formatting.
22+
- Do not introduce a notification domain until multiple Pi-facing notice/tool-result consumers need shared behavior.
623

724
## Reopen Triggers
825

9-
Create a concrete backlog slice when any of these become true:
26+
Create a concrete active slice when any of these become true:
1027

1128
- Runtime behavior changes or new domains expose a cohesive extraction opportunity in `index.ts`
1229
- Validation exposes drift in Flat Domain DAG boundaries, import invariants, package contents, or Telegram rendering/queue safety
1330
- User-visible Telegram behavior changes and needs README, docs, or changelog synchronization
31+
- Any queued Telegram control/prompt still needs a later incoming Telegram update to unstick after pi becomes idle
32+
- Telegram reactions fail to reprioritize/remove waiting voice, file, image, or media-group turns by source message id
1433
- A new explicit cleanup/refactor pass is requested and has a bounded, non-cosmetic target

CHANGELOG.md

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,21 @@
11
# Changelog
22

3+
## Unreleased
4+
5+
- `[Queue UX]` Telegram `/status` and `/model` now execute immediately instead of entering the control queue, and post-agent-end queue dispatch is deferred to the next event-loop turn so queued follow-ups are retried after pi has settled idle state. The pi status bar also shows specific busy labels such as `active`, `dispatching`, `queued`, `tool running`, and `model`, and docs/tests now clarify that reaction priority applies to voice/file/image/media turns without introducing pi steering semantics. Impact: status/model controls do not get stuck behind generation, queued work no longer needs a later Telegram update to unstick after agent end, and attachment turns keep predictable local priority behavior.
6+
- `[Context]` Compressed the durable domain-ownership map in `AGENTS.md`, rewrote the detailed `docs/architecture.md` ownership map as a compact domain table with boundary invariants, and codified that mirrored domain test helpers stay local unless reused across multiple suites. Impact: project context carries less duplication while preserving the source/test domain mirror.
7+
- `[Attachment Handlers]` Standardized inbound preprocessing on portable command templates and split docs into portable standard core (`docs/command-templates.md`) plus local attachment-handler adaptation (`docs/attachment-handlers.md`). Impact: voice/STT handlers can be configured without coupling pi-telegram to another extension's registry internals.
8+
- `[Attachment Fallbacks]` Matching attachment handlers now run as an ordered fallback chain: a failed matching handler records diagnostics and the next matching handler is tried before falling back to the normal attachment prompt. Impact: operators can configure primary/fallback STT chains directly in `telegram.json`.
9+
- `[Extension Boundaries]` Removed legacy attachment-handler execution through private auto-tool registries. Impact: pi-telegram now depends on portable command templates instead of another extension's config or registry shape.
10+
- `[Domain DAG]` Removed the broad `registration` domain and moved responsibilities into owning domains: attachments register `telegram_attach`, commands register pi `/telegram-*` commands, lifecycle registers pi hooks, and prompts own Telegram-specific system prompt injection. Impact: entrypoint wiring is clearer and each registration surface has focused tests.
11+
- `[telegram_attach]` Moved `telegram_attach` tool definition into the attachments domain, kept outbound size/queue limits there, recorded queueing failures through runtime events, and formatted tool results with pi-friendly spacing. Impact: outbound file delivery behavior is owned by the same domain that queues and sends Telegram attachments.
12+
- `[Docs]` Updated README, architecture notes, docs index, and backlog context for the command-template attachment-handler model and the new domain ownership split. Impact: user-facing setup and maintainer context match the 0.5.0 code shape.
13+
- `[Validation]` Added focused coverage for command registration, lifecycle hook registration, prompt injection, attachment tool registration, entrypoint wiring, and command-template handler behavior. Impact: the new domain boundaries are guarded by regression tests.
14+
315
## 0.4.0: Singleton Locks & Attachment Handlers
416

517
- `[Locks]` Added the shared `locks.json` singleton ownership standard and documented it in `docs/locks.md`. Telegram polling ownership now lives under `@llblab/pi-telegram` in `~/.pi/agent/locks.json`, while `telegram.json` remains pure bot/user configuration. `/telegram-connect` acquires the lock, replaces stale locks, or moves live external owners here through an interactive confirmation; `/telegram-disconnect` releases it. Session initialization reads ownership state, active owners stop local polling when `locks.json` no longer points at their own `pid`/`cwd`, session replacement via `/new` suspends polling/watchers without touching explicit ownership before resuming in the new session, and a reopened pi process resumes a stale same-`cwd` lock automatically. Impact: runtime locks can be reset or moved without deleting Telegram configuration, finding the previous pi instance, or crashing on stale extension contexts.
6-
- `[Attachment Handlers]` Added `telegram.json` inbound attachment handlers with MIME/type matching, safe command placeholder substitution, local tool invocation, compact `[attachments] <directory>` plus `[outputs]` prompt sections, and quiet omission of empty or failed handler output. Impact: common flows such as Telegram voice transcription can happen before the agent sees the turn while keeping source attachment paths visible.
18+
- `[Attachment Handlers]` Added `telegram.json` inbound attachment handlers with MIME/type matching, safe command placeholder substitution, compact `[attachments] <directory>` plus `[outputs]` prompt sections, and quiet omission of empty or failed handler output. Impact: common flows such as Telegram voice transcription can happen before the agent sees the turn while keeping source attachment paths visible.
719
- `[Refactor]` Extracted inbound route composition from `index.ts` into `/lib/routing.ts`, keeping paired update execution, callback menus, command-or-prompt dispatch, media grouping, prompt enqueueing, queued edits, and attachment-handler turn building behind one cohesive route wiring boundary. Impact: the entrypoint stays smaller while high-risk Telegram update flow remains covered by runtime and invariant tests.
820

921
## 0.3.0: Modular Runtime, Queue Controls, Diagnostics

0 commit comments

Comments
 (0)