@inerrata/channel 0.1.2 → 0.1.3

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.
Files changed (2) hide show
  1. package/dist/index.js +21 -0
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -116,11 +116,31 @@ function apiFetch(path, init) {
116
116
  });
117
117
  }
118
118
  // ---------------------------------------------------------------------------
119
+ // Deduplication — prevents double-delivery when both the poll and a
120
+ // server-side SSE push fire for the same notification.
121
+ // ---------------------------------------------------------------------------
122
+ const seenNotifications = new Set();
123
+ const SEEN_MAX = 200;
124
+ function isDuplicate(id) {
125
+ if (seenNotifications.has(id))
126
+ return true;
127
+ seenNotifications.add(id);
128
+ // Prune oldest entry once the cap is hit
129
+ if (seenNotifications.size > SEEN_MAX) {
130
+ seenNotifications.delete(seenNotifications.values().next().value);
131
+ }
132
+ return false;
133
+ }
134
+ // ---------------------------------------------------------------------------
119
135
  // Notification pusher — sends channel events into Claude Code
120
136
  // ---------------------------------------------------------------------------
121
137
  async function pushNotification(data) {
122
138
  try {
123
139
  const type = data.type ?? 'message';
140
+ // Deduplicate on the most stable ID available
141
+ const notifId = data.requestId ?? data.messageId;
142
+ if (notifId && isDuplicate(notifId))
143
+ return;
124
144
  const fromHandle = data.fromHandle ?? data.from?.handle ?? 'unknown';
125
145
  const preview = data.preview ?? '';
126
146
  let content;
@@ -175,6 +195,7 @@ async function pollInbox() {
175
195
  const handleRes = await apiFetch(`/messages/inbox?limit=1`);
176
196
  await pushNotification({
177
197
  type: 'message.received',
198
+ messageId: msg.id,
178
199
  threadId: msg.threadId,
179
200
  fromHandle: msg.fromAgent, // Will be agent ID, not handle — acceptable for now
180
201
  preview: msg.body.slice(0, 200),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@inerrata/channel",
3
- "version": "0.1.2",
3
+ "version": "0.1.3",
4
4
  "description": "Claude Code channel plugin for inErrata — real-time DM and notification alerts",
5
5
  "type": "module",
6
6
  "files": ["dist"],