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
This commit is contained in:
Nelson Pires
2026-02-23 00:05:13 +02:00
committed by GitHub
parent 74fa09225a
commit 2a3254495f
6 changed files with 68 additions and 2 deletions
+4
View File
@@ -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. OpenCode server integration utilities including config management, provider authentication, and UI authentication.
- Module docs: `packages/web/server/lib/opencode/DOCUMENTATION.md` - 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 ##### terminal
WebSocket protocol utilities for terminal input handling including message normalization, control frame parsing, and rate limiting. 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` - Module docs: `packages/web/server/lib/terminal/DOCUMENTATION.md`
+1 -1
View File
@@ -10,7 +10,7 @@ import os from 'os';
import crypto from 'crypto'; import crypto from 'crypto';
import { createUiAuth } from './lib/opencode/ui-auth.js'; import { createUiAuth } from './lib/opencode/ui-auth.js';
import { startCloudflareTunnel, printTunnelWarning, checkCloudflaredAvailable } from './lib/cloudflare-tunnel.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 { import {
TERMINAL_INPUT_WS_MAX_PAYLOAD_BYTES, TERMINAL_INPUT_WS_MAX_PAYLOAD_BYTES,
TERMINAL_INPUT_WS_PATH, TERMINAL_INPUT_WS_PATH,
@@ -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).
@@ -0,0 +1 @@
export { truncateNotificationText, prepareNotificationLastMessage } from './message.js';
@@ -1,6 +1,6 @@
import { describe, expect, it } from 'bun:test'; import { describe, expect, it } from 'bun:test';
import { prepareNotificationLastMessage, truncateNotificationText } from './notification-message.js'; import { prepareNotificationLastMessage, truncateNotificationText } from './message.js';
describe('notification message helpers', () => { describe('notification message helpers', () => {
it('truncates oversized notification text', () => { it('truncates oversized notification text', () => {