Skip to content

feat(notify): Add support for sending plain text messages - #929

Merged
tbrandenburg merged 5 commits into
mainfrom
feat/notify-plain-messages
Feb 2, 2026
Merged

feat(notify): Add support for sending plain text messages#929
tbrandenburg merged 5 commits into
mainfrom
feat/notify-plain-messages

Conversation

@tbrandenburg

Copy link
Copy Markdown
Owner

Problem

Currently, the work notify send command only supports sending notifications about existing work items via query syntax (where <query> to <target> or TASK-001 to <target>). Users cannot send arbitrary messages like status updates, announcements, or free-form notifications without creating a work item first.

Solution

Extended the work notify send command to accept a third syntax: work notify send "message content" to <target>. The command parser detects quoted message strings and bypasses the work item query path, formatting and sending the message directly to the specified target.

Detection heuristic: Messages containing spaces or newlines are treated as plain messages; single-word inputs are treated as task IDs.

Implementation approach: Uses a special marker work item (__plain_message__ ID) to signal plain message mode to handlers, avoiding breaking changes to the TargetHandler interface.

Changes

Core Implementation

  • src/cli/commands/notify/send.ts: Added third syntax branch for message detection
  • src/core/engine.ts: Added sendPlainNotification() method
  • src/core/notification-service.ts: Added sendPlainNotification() using marker work item
  • src/core/target-handlers/telegram-handler.ts: Added formatPlainMessage() with 📬 icon formatting

Testing

  • tests/e2e/telegram-notification.test.ts: Added e2e test for plain message delivery
  • All 389 tests passing (added 1 new test, 0 regressions)

Documentation

  • Added implementation plan and report in .claude/PRPs/

Testing

Validation Performed

  • ✅ Type-check passes (0 errors)
  • ✅ Lint passes (0 errors, 0 warnings)
  • ✅ Unit tests: 389 passed
  • ✅ E2E tests: All telegram tests pass including new plain message test
  • ✅ Build succeeds

Target Support

Target Plain Message Support Notes
telegram ✅ Full support Special formatting with 📬 icon, HTML escaping, 4096 char limit
bash ✅ Automatic Scripts receive message in JSON, can detect __plain_message__ marker

Example Usage

# Single-line message
work notify send "Deployment complete - all systems operational" to alerts

# Multi-line message (shell handles quotes)
work notify send 'Status Update:
✅ Tests passing
✅ Build successful  
🚀 Ready for deployment' to team-notifications

# Existing syntaxes still work unchanged
work notify send TASK-001 to alerts
work notify send where priority=high to alerts

Implementation Details

Security & Best Practices

  • HTML Escaping: User messages escaped (<, >, &) to prevent injection
  • Input Validation: Explicit validation per oclif strict=false best practices
  • Character Limits: Telegram 4096 char limit enforced with truncation notice
  • Current Standards: Verified against Telegram Bot API docs (2026-02-01)

Architecture Decisions

  • Marker Work Item Pattern: Chose __plain_message__ marker over interface extension for MVP simplicity
  • Detection Heuristic: "Spaces OR newlines" intuitive for users (task IDs are single words)
  • Handler-Level Formatting: Each handler formats according to its requirements

Notes

  • Multi-line messages work with proper shell quoting (user responsibility)
  • Bash handler automatically supports plain messages via JSON passthrough
  • Future: Could extend to proper TargetHandler interface method if needed
  • Implementation follows existing patterns and conventions throughout codebase

Related: Implementation of feature request for direct message notifications without work item dependency.

Tom Brandenburg added 5 commits February 1, 2026 17:36
Documentation showed shorthand syntax 'work notify send TASK-001 to alerts'
but implementation only accepted full syntax 'work notify send where <query> to <target>'.

Changes:
- Modified src/cli/commands/notify/send.ts to support both syntaxes
- Removed fixed arg definitions, using strict=false for flexible parsing
- Added argv parsing to detect shorthand vs full syntax
- Shorthand 'TASK-001 to alerts' is converted to 'id=TASK-001'
- Added test case for shorthand syntax in notify-workflow.test.ts
- Updated examples to show shorthand first

Fixes #853
Prevent malformed query 'id=' when task ID is empty.
Addresses code review feedback.
…tion targets

Users can now send arbitrary multi-line messages directly to notification
targets without creating work items. This extends notify send with a third
syntax: `work notify send "message" to <target>` alongside existing work
item notification methods.

Changes:
- Add message syntax detection in notify/send command (spaces/newlines trigger message mode)
- Implement WorkEngine.sendPlainNotification() method
- Add NotificationService.sendPlainNotification() using special marker work item
- Extend TelegramTargetHandler with formatPlainMessage() for 📬 formatted output
- Add e2e test validating plain message delivery

Pattern: Uses __plain_message__ marker work item to signal plain text mode
Decision: Marker approach avoids breaking TargetHandler interface changes
Related: Bash handler automatically supports plain messages via JSON passthrough
Testing: 389 tests passing including new e2e telegram plain message test

Implementation verified against current Telegram Bot API standards (HTML
escaping, parse_mode, character limits) and oclif strict=false best practices.
Resolved conflicts in src/cli/commands/notify/send.ts:
- Main branch added shorthand syntax support (PR #853)
- This branch adds message syntax support
- Merged to support all three syntaxes: message, shorthand, where clause
@tbrandenburg
tbrandenburg merged commit b507448 into main Feb 2, 2026
4 checks passed
@tbrandenburg
tbrandenburg deleted the feat/notify-plain-messages branch February 2, 2026 05:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant