From 2a3254495fa220faf26d9a497fa094f5e1db3079 Mon Sep 17 00:00:00 2001 From: Nelson Pires Date: Sun, 22 Feb 2026 19:05:13 -0300 Subject: [PATCH] refactor(notifications): move notification helpers into dedicated module boundary (#484) * refactor(notifications): move message helper into domain module * test(notifications): move helper tests to new module path * refactor(notifications): add stable module entrypoint * refactor(server): route notification imports through domain boundary * docs(notifications): add module reference documentation * docs: map notifications module in AGENTS --- AGENTS.md | 4 ++ packages/web/server/index.js | 2 +- .../server/lib/notifications/DOCUMENTATION.md | 61 +++++++++++++++++++ .../web/server/lib/notifications/index.js | 1 + .../message.js} | 0 .../message.test.js} | 2 +- 6 files changed, 68 insertions(+), 2 deletions(-) create mode 100644 packages/web/server/lib/notifications/DOCUMENTATION.md create mode 100644 packages/web/server/lib/notifications/index.js rename packages/web/server/lib/{notification-message.js => notifications/message.js} (100%) rename packages/web/server/lib/{notification-message.test.js => notifications/message.test.js} (97%) diff --git a/AGENTS.md b/AGENTS.md index 962de8e7..6c5f32f9 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -49,6 +49,10 @@ GitHub authentication, OAuth device flow, Octokit client factory, and repository OpenCode server integration utilities including config management, provider authentication, and UI authentication. - Module docs: `packages/web/server/lib/opencode/DOCUMENTATION.md` +##### notifications +Notification message preparation utilities for system notifications, including text truncation and optional summarization. +- Module docs: `packages/web/server/lib/notifications/DOCUMENTATION.md` + ##### terminal WebSocket protocol utilities for terminal input handling including message normalization, control frame parsing, and rate limiting. - Module docs: `packages/web/server/lib/terminal/DOCUMENTATION.md` diff --git a/packages/web/server/index.js b/packages/web/server/index.js index 10092ce8..083605f0 100644 --- a/packages/web/server/index.js +++ b/packages/web/server/index.js @@ -10,7 +10,7 @@ import os from 'os'; import crypto from 'crypto'; import { createUiAuth } from './lib/opencode/ui-auth.js'; import { startCloudflareTunnel, printTunnelWarning, checkCloudflaredAvailable } from './lib/cloudflare-tunnel.js'; -import { prepareNotificationLastMessage } from './lib/notification-message.js'; +import { prepareNotificationLastMessage } from './lib/notifications/index.js'; import { TERMINAL_INPUT_WS_MAX_PAYLOAD_BYTES, TERMINAL_INPUT_WS_PATH, diff --git a/packages/web/server/lib/notifications/DOCUMENTATION.md b/packages/web/server/lib/notifications/DOCUMENTATION.md new file mode 100644 index 00000000..0d0873d7 --- /dev/null +++ b/packages/web/server/lib/notifications/DOCUMENTATION.md @@ -0,0 +1,61 @@ +# Notifications Module Documentation + +## Purpose +This module provides notification message preparation utilities for the web server runtime, including text truncation and optional message summarization for system notifications. + +## Entrypoints and structure +- `packages/web/server/lib/notifications/index.js`: public entrypoint imported by `packages/web/server/index.js`. +- `packages/web/server/lib/notifications/message.js`: helper implementation module. +- `packages/web/server/lib/notifications/message.test.js`: unit tests for notification message helpers. + +## Public exports + +### Notifications API (re-exported from message.js) +- `truncateNotificationText(text, maxLength)`: Truncates text to specified max length, appending `...` if truncated. +- `prepareNotificationLastMessage({ message, settings, summarize })`: Prepares the last message for notification display, with optional summarization support. + +## Constants + +### Default values +- `DEFAULT_NOTIFICATION_MESSAGE_MAX_LENGTH`: 250 (default max length for notification text). +- `DEFAULT_NOTIFICATION_SUMMARY_THRESHOLD`: 200 (minimum message length to trigger summarization). +- `DEFAULT_NOTIFICATION_SUMMARY_LENGTH`: 100 (target length for summarized messages). + +## Settings object format + +The `settings` parameter for `prepareNotificationLastMessage` supports: +- `summarizeLastMessage` (boolean): Whether to enable summarization for long messages. +- `summaryThreshold` (number): Minimum message length to trigger summarization (default: 200). +- `summaryLength` (number): Target length for summarized messages (default: 100). +- `maxLastMessageLength` (number): Maximum length for the final notification text (default: 250). + +## Response contracts + +### `truncateNotificationText` +- Returns empty string for non-string input. +- Returns original text if under max length. +- Returns `${text.slice(0, maxLength)}...` for truncated text. + +### `prepareNotificationLastMessage` +- Returns empty string for empty/null message. +- Returns truncated original message if summarization disabled, message under threshold, or summarization fails. +- Returns truncated summary if summarization succeeds and returns non-empty string. +- Always applies `maxLastMessageLength` truncation to final result. + +## Notes for contributors + +### Adding new notification helpers +1. Add new helper functions to `packages/web/server/lib/notifications/message.js`. +2. Export functions that are intended for public use. +3. Follow existing patterns for input validation (e.g., type checking for strings). +4. Use `resolvePositiveNumber` for numeric parameters with fallbacks to maintain safe defaults. +5. Add corresponding unit tests in `packages/web/server/lib/notifications/message.test.js`. + +### Error handling +- `prepareNotificationLastMessage` catches summarization errors and falls back to original message. +- Invalid numeric parameters default to safe fallback values. +- Non-string inputs are handled gracefully (return empty string). + +### Testing +- Run `bun run type-check`, `bun run lint`, and `bun run build` before finalizing changes. +- Unit tests should cover truncation behavior, summarization success/failure, and edge cases (empty strings, invalid inputs). diff --git a/packages/web/server/lib/notifications/index.js b/packages/web/server/lib/notifications/index.js new file mode 100644 index 00000000..fb5cecd4 --- /dev/null +++ b/packages/web/server/lib/notifications/index.js @@ -0,0 +1 @@ +export { truncateNotificationText, prepareNotificationLastMessage } from './message.js'; diff --git a/packages/web/server/lib/notification-message.js b/packages/web/server/lib/notifications/message.js similarity index 100% rename from packages/web/server/lib/notification-message.js rename to packages/web/server/lib/notifications/message.js diff --git a/packages/web/server/lib/notification-message.test.js b/packages/web/server/lib/notifications/message.test.js similarity index 97% rename from packages/web/server/lib/notification-message.test.js rename to packages/web/server/lib/notifications/message.test.js index 16201db1..8d4f74cd 100644 --- a/packages/web/server/lib/notification-message.test.js +++ b/packages/web/server/lib/notifications/message.test.js @@ -1,6 +1,6 @@ import { describe, expect, it } from 'bun:test'; -import { prepareNotificationLastMessage, truncateNotificationText } from './notification-message.js'; +import { prepareNotificationLastMessage, truncateNotificationText } from './message.js'; describe('notification message helpers', () => { it('truncates oversized notification text', () => {