diff --git a/CHANGELOG.md b/CHANGELOG.md index e900ce0..963c58f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,27 @@ # Changelog +## 0.8.0 - 2026-06-14 + +- Added cross-messenger live progress updates so supported Slack, Discord, and Telegram destinations update an existing progress message where possible instead of posting repeated snapshots. #78 +- Added Slack progress message references and `chat.update` support, with recoverable fallback to a new live progress message or plain text snapshot when updates fail. #78 +- Added Discord progress message references and bot-message edit support, with the same best-effort fallback semantics used by other messengers. #78 +- Shared the live progress delivery fallback model across runtimes: update existing progress, send a new live/editable progress message, then send a plain snapshot while keeping failures non-fatal. #78 +- Hardened stale/revoked/moved binding authority coverage so live progress refs are not edited after destination authority changes. #78 +- Improved relay progress UX with coalesced milestone progress, live-edit support for Telegram broker/direct paths, terminal-output separation, and safer progress-mode behavior. #77 +- Fixed broker state update queue and locking behavior to keep relay state writes serialized and resilient under concurrent broker activity. #75 #76 + +## 0.7.2 - 2026-06-14 + +- Fixed npm publishing for the scoped `@zylab/pirelay` package. #74 + +## 0.7.1 - 2026-06-14 + +- Added remote skill invocation so authorized messenger users can list and invoke allowed local Pi skills from paired sessions. #70 +- Added requester-scoped remote approval gates, shared-room agent delegation, and GIF image prompt support. #60 #61 #64 #66 +- Fixed Telegram broker pairing and reconnect resilience, readable terminal output rendering, Telegram markdown output, and streamed assistant output fallback behavior. #59 #65 #68 #69 +- Hardened approval action routing and archived completed OpenSpec changes. #62 #67 +- Fixed npm package public publishing and release preparation. #72 #73 + ## 0.7.0 - 2026-05-15 - Added messenger command surfaces: Telegram BotCommand menus, Discord native `/relay` command metadata/routing, and Slack `/pirelay` slash-command manifest and runtime support. #56 diff --git a/openspec/changes/update-live-progress-across-messengers/.openspec.yaml b/openspec/changes/archive/2026-06-14-update-live-progress-across-messengers/.openspec.yaml similarity index 100% rename from openspec/changes/update-live-progress-across-messengers/.openspec.yaml rename to openspec/changes/archive/2026-06-14-update-live-progress-across-messengers/.openspec.yaml diff --git a/openspec/changes/update-live-progress-across-messengers/design.md b/openspec/changes/archive/2026-06-14-update-live-progress-across-messengers/design.md similarity index 100% rename from openspec/changes/update-live-progress-across-messengers/design.md rename to openspec/changes/archive/2026-06-14-update-live-progress-across-messengers/design.md diff --git a/openspec/changes/update-live-progress-across-messengers/proposal.md b/openspec/changes/archive/2026-06-14-update-live-progress-across-messengers/proposal.md similarity index 100% rename from openspec/changes/update-live-progress-across-messengers/proposal.md rename to openspec/changes/archive/2026-06-14-update-live-progress-across-messengers/proposal.md diff --git a/openspec/changes/update-live-progress-across-messengers/specs/discord-runtime-client/spec.md b/openspec/changes/archive/2026-06-14-update-live-progress-across-messengers/specs/discord-runtime-client/spec.md similarity index 100% rename from openspec/changes/update-live-progress-across-messengers/specs/discord-runtime-client/spec.md rename to openspec/changes/archive/2026-06-14-update-live-progress-across-messengers/specs/discord-runtime-client/spec.md diff --git a/openspec/changes/update-live-progress-across-messengers/specs/messenger-relay-sessions/spec.md b/openspec/changes/archive/2026-06-14-update-live-progress-across-messengers/specs/messenger-relay-sessions/spec.md similarity index 100% rename from openspec/changes/update-live-progress-across-messengers/specs/messenger-relay-sessions/spec.md rename to openspec/changes/archive/2026-06-14-update-live-progress-across-messengers/specs/messenger-relay-sessions/spec.md diff --git a/openspec/changes/update-live-progress-across-messengers/specs/relay-channel-adapters/spec.md b/openspec/changes/archive/2026-06-14-update-live-progress-across-messengers/specs/relay-channel-adapters/spec.md similarity index 100% rename from openspec/changes/update-live-progress-across-messengers/specs/relay-channel-adapters/spec.md rename to openspec/changes/archive/2026-06-14-update-live-progress-across-messengers/specs/relay-channel-adapters/spec.md diff --git a/openspec/changes/update-live-progress-across-messengers/specs/slack-runtime-client/spec.md b/openspec/changes/archive/2026-06-14-update-live-progress-across-messengers/specs/slack-runtime-client/spec.md similarity index 100% rename from openspec/changes/update-live-progress-across-messengers/specs/slack-runtime-client/spec.md rename to openspec/changes/archive/2026-06-14-update-live-progress-across-messengers/specs/slack-runtime-client/spec.md diff --git a/openspec/changes/update-live-progress-across-messengers/tasks.md b/openspec/changes/archive/2026-06-14-update-live-progress-across-messengers/tasks.md similarity index 100% rename from openspec/changes/update-live-progress-across-messengers/tasks.md rename to openspec/changes/archive/2026-06-14-update-live-progress-across-messengers/tasks.md diff --git a/openspec/specs/discord-runtime-client/spec.md b/openspec/specs/discord-runtime-client/spec.md index 8f26764..c6a7d5b 100644 --- a/openspec/specs/discord-runtime-client/spec.md +++ b/openspec/specs/discord-runtime-client/spec.md @@ -110,3 +110,21 @@ The system SHALL provide secret-safe diagnostics for live Discord runtime readin - **WHEN** the local user invokes `/relay setup discord` - **THEN** the system includes Developer Portal setup guidance, token/client-id instructions, required invite scope guidance, and DM-first pairing instructions +### Requirement: Discord live client supports progress message edits +The Discord live client SHALL expose bot-message references and edit operations needed for live progress edit-in-place behavior while preserving safe fallback when Discord rejects an edit. + +#### Scenario: Discord send message returns id reference +- **WHEN** PiRelay sends a Discord bot message for live progress +- **THEN** the Discord live client returns the created message id when Discord provides it +- **AND** that id can be used as a live progress reference scoped to the Discord channel destination + +#### Scenario: Discord edits progress message +- **WHEN** PiRelay has a Discord live progress reference for a bot-owned message and progress text changes +- **THEN** the Discord live client edits the expected channel message using the platform message id +- **AND** it keeps equivalent safe text content even if richer formatting or components are later added + +#### Scenario: Discord edit failure is recoverable +- **WHEN** Discord rejects a live progress edit because the message is deleted, inaccessible, not bot-owned, or permissions changed +- **THEN** PiRelay clears the stale Discord progress reference and falls back to a new live progress message or plain snapshot +- **AND** it does not mark Discord runtime unhealthy solely because a best-effort progress edit failed + diff --git a/openspec/specs/messenger-relay-sessions/spec.md b/openspec/specs/messenger-relay-sessions/spec.md index 0e908ec..bc558f3 100644 --- a/openspec/specs/messenger-relay-sessions/spec.md +++ b/openspec/specs/messenger-relay-sessions/spec.md @@ -927,3 +927,31 @@ The system SHALL notify eligible paired messenger bindings when a Pi session com - **THEN** PiRelay verifies the destination remains an active authorized binding according to existing binding authority and adapter delivery rules - **AND** it does not send the notification to revoked, paused, unauthorized, missing, or stale destinations +### Requirement: Live progress updates use in-place delivery where supported +The system SHALL deliver non-terminal live progress as an updated per-destination progress message when the active messenger adapter supports bot-message updates, while preserving safe snapshot fallback for unsupported or failed update paths. + +#### Scenario: Supported adapter updates existing progress +- **WHEN** a paired running session emits multiple eligible progress updates for a binding whose messenger adapter supports live progress updates +- **THEN** PiRelay updates the existing live progress message for that destination rather than sending a new message for each progress flush +- **AND** the progress content remains coalesced, rate-limited, redacted, and bounded by configured progress limits + +#### Scenario: Unsupported adapter sends snapshots +- **WHEN** a paired running session emits eligible progress updates for a binding whose messenger adapter does not support live progress updates +- **THEN** PiRelay sends bounded coalesced progress snapshots according to the binding's progress mode +- **AND** it does not treat missing edit capability as an adapter failure + +#### Scenario: Update failure falls back safely +- **WHEN** updating an existing live progress message fails because the message was deleted, expired, inaccessible, or rejected by the platform +- **THEN** PiRelay clears that live progress reference and falls back to sending a new live progress message or plain snapshot +- **AND** final failure to deliver progress is swallowed because non-terminal progress is best-effort + +#### Scenario: Terminal output remains separate +- **WHEN** a Pi turn completes, fails, or aborts after live progress updates were sent or edited +- **THEN** PiRelay sends terminal output or notification according to final-output policy as a separate messenger result +- **AND** it does not merge final assistant output into the live progress card + +#### Scenario: Progress modes still apply independently +- **WHEN** one binding is normal, another is verbose, another is completion-only, and another is quiet +- **THEN** live progress update/edit behavior respects each binding's existing progress-mode eligibility independently +- **AND** quiet receives no live progress while completion-only receives no ordinary live progress + diff --git a/openspec/specs/relay-channel-adapters/spec.md b/openspec/specs/relay-channel-adapters/spec.md index 5fb6000..6043746 100644 --- a/openspec/specs/relay-channel-adapters/spec.md +++ b/openspec/specs/relay-channel-adapters/spec.md @@ -318,3 +318,26 @@ Messenger adapters SHALL normalize inbound GIF media as convertible image input - **WHEN** shared relay code constructs Pi image prompt content from a GIF attachment - **THEN** the emitted image content uses the converted static image MIME type and data, not the original raw GIF MIME type and bytes +### Requirement: Channel adapters expose optional live progress update capability +The system SHALL model live progress message creation and update as optional channel adapter capabilities with safe fallback to ordinary text messages when a platform lacks update support or an update operation fails. + +#### Scenario: Adapter returns live progress reference +- **WHEN** a channel adapter supports live progress and sends a live progress message +- **THEN** it returns a non-secret message reference sufficient to update that bot-owned message later +- **AND** the reference is scoped to the destination and is not persisted as a long-term binding secret + +#### Scenario: Adapter updates live progress reference +- **WHEN** a channel adapter receives a valid live progress reference for a bot-owned message in the expected destination +- **THEN** it updates that message with the new safe progress text using platform-specific APIs +- **AND** it falls back to ordinary text delivery or reports a recoverable failure when the update cannot be performed + +#### Scenario: Adapter fallback invariant is consistent +- **WHEN** live progress delivery is attempted through Telegram, Slack, Discord, or a future adapter +- **THEN** the delivery path tries update-in-place first when a reference exists, then sends a new live/editable progress message when supported, then sends a plain text snapshot +- **AND** if every attempt fails, the failure is contained as best-effort progress and does not fail the Pi turn or mark the messenger runtime unhealthy + +#### Scenario: Binding authority is checked before protected progress delivery +- **WHEN** live progress is about to be sent or updated through any adapter +- **THEN** PiRelay verifies the current binding authority, destination identity, paused/revoked/moved state, and route liveness for that destination +- **AND** refuses to send or update protected progress when authority is unavailable or denied + diff --git a/openspec/specs/slack-runtime-client/spec.md b/openspec/specs/slack-runtime-client/spec.md index e4faf20..86e5bcc 100644 --- a/openspec/specs/slack-runtime-client/spec.md +++ b/openspec/specs/slack-runtime-client/spec.md @@ -2,7 +2,6 @@ ## Purpose Slack runtime client defines PiRelay's live Slack Socket Mode runtime behavior, including lifecycle management, event acknowledgement and deduplication, workspace/bot identity discovery, safe Web API operations, and secret-safe diagnostics. - ## Requirements ### Requirement: Live Slack Socket Mode lifecycle The system SHALL start, monitor, reconnect, and stop a live Slack Socket Mode runtime when Slack relay is explicitly enabled and configured with the required credentials. @@ -97,3 +96,21 @@ The system SHALL expose secret-safe diagnostics for live Slack runtime readiness - **THEN** displayed and logged diagnostics include the Slack method and non-secret error code or category - **AND** they redact bot tokens, app-level tokens, signing secrets, authorization headers, Socket Mode URLs, response URLs, pairing codes, and hidden prompt content +### Requirement: Slack live client supports progress message updates +The Slack live client SHALL expose bot-message references and update operations needed for live progress edit-in-place behavior while preserving safe fallback when Slack rejects an update. + +#### Scenario: Slack post message returns timestamp reference +- **WHEN** PiRelay posts a Slack bot message for live progress +- **THEN** the Slack live client returns the message timestamp `ts` when Slack provides it +- **AND** that timestamp can be used as a live progress reference scoped to the Slack channel or thread destination + +#### Scenario: Slack updates progress message +- **WHEN** PiRelay has a Slack live progress reference for a bot-owned message and progress text changes +- **THEN** the Slack live client calls Slack `chat.update` for the expected channel and timestamp +- **AND** it preserves equivalent safe text content even if richer formatting is later added + +#### Scenario: Slack update failure is recoverable +- **WHEN** Slack rejects a live progress update because the message is deleted, too old, not bot-owned, or otherwise inaccessible +- **THEN** PiRelay clears the stale Slack progress reference and falls back to a new live progress message or plain snapshot +- **AND** it does not mark Slack runtime unhealthy solely because a best-effort progress update failed + diff --git a/package-lock.json b/package-lock.json index 6c72a6b..2ac2074 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@zylab/pirelay", - "version": "0.7.2", + "version": "0.8.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@zylab/pirelay", - "version": "0.7.2", + "version": "0.8.0", "license": "MIT", "dependencies": { "@mariozechner/jiti": "^2.6.5", diff --git a/package.json b/package.json index f6cfe27..c08252a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@zylab/pirelay", - "version": "0.7.2", + "version": "0.8.0", "description": "Pi package that pairs messenger chats to active Pi sessions for notifications and remote control.", "type": "module", "license": "MIT",