@llblab/pi-telegram 0.48.0 → 0.48.1

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/AGENTS.md CHANGED
@@ -92,7 +92,7 @@ Use the relevant local skill before non-trivial work in its domain. Keep skill o
92
92
 
93
93
  ### 4.4 Queue, Delivery, And User Surfaces
94
94
 
95
- - Queue lane/kind admission is explicit. Dispatch waits for active-turn, pending-dispatch, control, compaction, `ctx.isIdle()`, and Pi pending-message guards; a dispatched prompt stays queued until `agent_start` consumes it. Each prompt is one object with one active lane and no reserved return slot. Normal and Priority are separate FIFO lanes: crossing lanes removes it from the source and appends it at the destination tail, while Keep/Skip and same-category emoji changes preserve lane position. Complete reaction sets independently derive Priority from recognized positive emoji and Skip from recognized negative emoji; both may coexist, suppressed turns retain durable receipts while waiting, and Skip settles them only when the prompt reaches dispatch before dropping it without inference. Suppressed turns remain visible at a struck-through physical ordinal without contributing to executable queue counters, while graceful session shutdown discards all remaining queue authority before clearing memory.
95
+ - Queue lane/kind admission is explicit. Dispatch waits for active-turn, pending-dispatch, control, compaction, `ctx.isIdle()`, and Pi pending-message guards; a dispatched prompt stays queued until `agent_start` consumes it. The terminal `+N` suffix is a yellow count of executable prompts still waiting, excludes the dispatched head immediately, and never counts current agent work from any source. Each prompt is one object with one active lane and no reserved return slot. Normal and Priority are separate FIFO lanes: crossing lanes removes it from the source and appends it at the destination tail, while Keep/Skip and same-category emoji changes preserve lane position. Complete reaction sets independently derive Priority from recognized positive emoji and Skip from recognized negative emoji; both may coexist, suppressed turns retain durable receipts while waiting, and Skip settles them only when the prompt reaches dispatch before dropping it without inference. Suppressed turns remain visible at a struck-through physical ordinal without contributing to executable queue counters, while graceful session shutdown discards all remaining queue authority before clearing memory.
96
96
  - `/stop`, `/abort`, `/next`, and `/continue` respectively reset+abort, abort while preserving queue, force the next turn, and enqueue a control-lane continuation. Abort-history folding applies only to Telegram-owned active turns.
97
97
  - Telegram extension side effects must not hold Pi's core lifecycle hostage after semantic completion. Preserve ordering in extension-owned background work, record failures, and fence target/profile/transport/session authority.
98
98
  - Complete assistant/guest model answers use Telegram-native Rich Markdown. Harness-owned menus, status, diagnostics, thinking, and tool evidence remain explicit HTML/plain or their documented native surface. Before Telegram preview or final delivery, strip every assistant-authored HTML comment regardless of Markdown position while keeping action activation top-level-only; a comment-only result sends no text message. Preserve literal code outside comments and structurally safe chunking; never split invalid markup.
package/CHANGELOG.md CHANGED
@@ -4,6 +4,10 @@
4
4
 
5
5
  ## Unreleased
6
6
 
7
+ ## 0.48.1: Truthful terminal queue count hotfix
8
+
9
+ - `Terminal queue status`: The yellow `+N` suffix now counts only executable prompts still waiting in the Telegram queue. The current agent run never contributes—whether it started from Telegram, the terminal, or autonomous continuation—and a dispatched Telegram prompt leaves the visible count before its run settles.
10
+
7
11
  ## 0.48.0: Unified activity and Thread display
8
12
 
9
13
  - `Unified activity`: The terminal keeps its stable `connected`, `leader`, or `follower` identity while work runs. Active work uses the same green Queue count as queued items, while Telegram typing projects every agent run—including local or autonomous work—into the assigned Thread and aggregate `All` target.
package/README.md CHANGED
@@ -200,7 +200,7 @@ Messages sent while Pi is busy become queued turns. Queue controls let you inspe
200
200
 
201
201
  Queue policy:
202
202
 
203
- - One prompt is one queue object with exactly one current lane and one current position; it never reserves a shadow place in the other lane.
203
+ - One prompt is one queue object with exactly one current lane and one current position; it never reserves a shadow place in the other lane. The terminal's yellow `+N` suffix counts only executable prompts still waiting, never the current run; a dispatched Telegram prompt stops contributing before that run settles.
204
204
  - Priority and Normal are separate FIFO lanes; Priority dispatches first.
205
205
  - Moving `Normal → Priority` removes the prompt from Normal and places it at the Priority tail. Moving `Priority → Normal` removes it from Priority and places it at the Normal tail; no former position is restored.
206
206
  - Keep/Skip never changes lane position. Skip preserves durable authority while waiting so Keep remains reversible, then settles that authority and drops the prompt without a model turn when dispatch reaches it. Skipped prompts stay visible at their physical queue position with a struck-through ordinal, but are excluded immediately from the executable queue count shown in both the Pi status bar and Telegram main menu. Graceful session shutdown discards all remaining queued authority, so a new session starts empty.
@@ -215,19 +215,13 @@ export function createTelegramBridgeStatusRuntime(deps) {
215
215
  getStatusBarState: (_ctx, error) => {
216
216
  const config = deps.getConfig();
217
217
  const queuedItems = deps.getQueuedItems();
218
- const queuedItemCount = deps.getQueuedItemCount?.(queuedItems) ?? queuedItems.length;
219
- const hasActiveTurn = deps.hasActiveTurn();
220
218
  const hasPendingDispatch = deps.hasDispatchPending();
219
+ const waitingItems = hasPendingDispatch ? queuedItems.slice(1) : queuedItems;
220
+ const queuedItemCount = deps.getQueuedItemCount?.(waitingItems) ?? waitingItems.length;
221
+ const hasActiveTurn = deps.hasActiveTurn();
221
222
  const hasPendingModelSwitch = deps.hasPendingModelSwitch();
222
223
  const activeToolExecutions = deps.getActiveToolExecutions();
223
224
  const compactionInProgress = deps.isCompactionInProgress();
224
- const activeWorkCount = hasActiveTurn ||
225
- hasPendingModelSwitch ||
226
- activeToolExecutions > 0 ||
227
- compactionInProgress ||
228
- (hasPendingDispatch && queuedItemCount === 0)
229
- ? 1
230
- : 0;
231
225
  const localBus = deps.getLocalBus?.();
232
226
  return {
233
227
  hasBotToken: config.botHasToken ?? Boolean(config.botToken),
@@ -251,9 +245,7 @@ export function createTelegramBridgeStatusRuntime(deps) {
251
245
  activeToolExecutions,
252
246
  queuedItems: queuedItemCount,
253
247
  }),
254
- queuedStatus: activeWorkCount + queuedItemCount > 0
255
- ? ` +${activeWorkCount + queuedItemCount}`
256
- : "",
248
+ queuedStatus: queuedItemCount > 0 ? ` +${queuedItemCount}` : "",
257
249
  pollingStopReason: deps.getPollingState?.().stopReason,
258
250
  error,
259
251
  };
@@ -414,7 +406,7 @@ function getTelegramStatusBarLabel(state) {
414
406
  export function buildTelegramStatusBarText(theme, state) {
415
407
  const label = theme.fg("accent", getTelegramStatusBarLabel(state));
416
408
  const queued = state.queuedStatus
417
- ? theme.fg("success", state.queuedStatus)
409
+ ? theme.fg("warning", state.queuedStatus)
418
410
  : "";
419
411
  if (!state.hasBotToken)
420
412
  return `${label} ${theme.fg("muted", "not configured")}${queued}`;
package/dist/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@llblab/pi-telegram",
3
- "version": "0.48.0",
3
+ "version": "0.48.1",
4
4
  "private": false,
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -452,7 +452,9 @@ Long-text split recovery remains conservative: only human text at or above the n
452
452
 
453
453
  ### Queue And Dispatch Safety
454
454
 
455
- The bridge keeps its own Telegram queue. Queue items have two explicit dimensions:
455
+ The bridge keeps its own Telegram queue. The Pi status bar's yellow `+N` suffix projects only executable prompts still waiting: current agent work from Telegram, terminal, or autonomous sources never contributes, and the dispatched Telegram head is subtracted while it remains retained pending `agent_start` consumption.
456
+
457
+ Queue items have two explicit dimensions:
456
458
 
457
459
  - `kind`: `prompt` or `control`.
458
460
  - `queueLane`: `control`, `priority`, or `default`.
package/lib/status.ts CHANGED
@@ -705,20 +705,14 @@ export function createTelegramBridgeStatusRuntime<
705
705
  getStatusBarState: (_ctx, error) => {
706
706
  const config = deps.getConfig();
707
707
  const queuedItems = deps.getQueuedItems();
708
- const queuedItemCount = deps.getQueuedItemCount?.(queuedItems) ?? queuedItems.length;
709
- const hasActiveTurn = deps.hasActiveTurn();
710
708
  const hasPendingDispatch = deps.hasDispatchPending();
709
+ const waitingItems = hasPendingDispatch ? queuedItems.slice(1) : queuedItems;
710
+ const queuedItemCount =
711
+ deps.getQueuedItemCount?.(waitingItems) ?? waitingItems.length;
712
+ const hasActiveTurn = deps.hasActiveTurn();
711
713
  const hasPendingModelSwitch = deps.hasPendingModelSwitch();
712
714
  const activeToolExecutions = deps.getActiveToolExecutions();
713
715
  const compactionInProgress = deps.isCompactionInProgress();
714
- const activeWorkCount =
715
- hasActiveTurn ||
716
- hasPendingModelSwitch ||
717
- activeToolExecutions > 0 ||
718
- compactionInProgress ||
719
- (hasPendingDispatch && queuedItemCount === 0)
720
- ? 1
721
- : 0;
722
716
  const localBus = deps.getLocalBus?.();
723
717
  return {
724
718
  hasBotToken: config.botHasToken ?? Boolean(config.botToken),
@@ -743,10 +737,7 @@ export function createTelegramBridgeStatusRuntime<
743
737
  activeToolExecutions,
744
738
  queuedItems: queuedItemCount,
745
739
  }),
746
- queuedStatus:
747
- activeWorkCount + queuedItemCount > 0
748
- ? ` +${activeWorkCount + queuedItemCount}`
749
- : "",
740
+ queuedStatus: queuedItemCount > 0 ? ` +${queuedItemCount}` : "",
750
741
  pollingStopReason: deps.getPollingState?.().stopReason,
751
742
  error,
752
743
  };
@@ -935,7 +926,7 @@ export function buildTelegramStatusBarText(
935
926
  ): string {
936
927
  const label = theme.fg("accent", getTelegramStatusBarLabel(state));
937
928
  const queued = state.queuedStatus
938
- ? theme.fg("success", state.queuedStatus)
929
+ ? theme.fg("warning", state.queuedStatus)
939
930
  : "";
940
931
  if (!state.hasBotToken)
941
932
  return `${label} ${theme.fg("muted", "not configured")}${queued}`;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@llblab/pi-telegram",
3
- "version": "0.48.0",
3
+ "version": "0.48.1",
4
4
  "private": false,
5
5
  "publishConfig": {
6
6
  "access": "public"