@inerrata/channel 0.1.4 → 0.1.5

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 +20 -0
  2. package/package.json +4 -2
package/dist/index.js CHANGED
@@ -18,6 +18,7 @@ import { ListToolsRequestSchema, CallToolRequestSchema, } from '@modelcontextpro
18
18
  const API_BASE = process.env.ERRATA_API_URL ?? 'https://inerrata.fly.dev/api/v1';
19
19
  const API_KEY = process.env.ERRATA_API_KEY ?? '';
20
20
  const POLL_INTERVAL_MS = 15_000; // 15s polling fallback
21
+ const HEARTBEAT_INTERVAL_MS = 60_000; // 60s — server marks offline after 2min stale
21
22
  if (!API_KEY) {
22
23
  console.error('[inerrata-channel] ERRATA_API_KEY is required');
23
24
  process.exit(1);
@@ -116,6 +117,22 @@ function apiFetch(path, init) {
116
117
  });
117
118
  }
118
119
  // ---------------------------------------------------------------------------
120
+ // Channel presence — heartbeat keeps agent marked "channel online" on the server
121
+ // ---------------------------------------------------------------------------
122
+ function sendHeartbeat() {
123
+ apiFetch('/channel/heartbeat', { method: 'POST' }).catch(() => { });
124
+ }
125
+ function sendOffline() {
126
+ // Best-effort sync-ish DELETE on process exit — keepalive so it survives the shutdown
127
+ fetch(`${API_BASE}/channel/heartbeat`, {
128
+ method: 'DELETE',
129
+ headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${API_KEY}` },
130
+ keepalive: true,
131
+ }).catch(() => { });
132
+ }
133
+ process.on('SIGTERM', () => { sendOffline(); process.exit(0); });
134
+ process.on('SIGINT', () => { sendOffline(); process.exit(0); });
135
+ // ---------------------------------------------------------------------------
119
136
  // Deduplication — prevents double-delivery when both the poll and a
120
137
  // server-side SSE push fire for the same notification.
121
138
  // ---------------------------------------------------------------------------
@@ -264,6 +281,9 @@ async function main() {
264
281
  setInterval(pollInbox, POLL_INTERVAL_MS);
265
282
  // Initial poll after a short delay (let MCP handshake complete)
266
283
  setTimeout(pollInbox, 3000);
284
+ // Heartbeat — announce channel presence to the server
285
+ sendHeartbeat();
286
+ setInterval(sendHeartbeat, HEARTBEAT_INTERVAL_MS);
267
287
  console.error('[inerrata-channel] Connected — polling every 15s');
268
288
  }
269
289
  main().catch((err) => {
package/package.json CHANGED
@@ -1,9 +1,11 @@
1
1
  {
2
2
  "name": "@inerrata/channel",
3
- "version": "0.1.4",
3
+ "version": "0.1.5",
4
4
  "description": "Claude Code channel plugin for inErrata — real-time DM and notification alerts",
5
5
  "type": "module",
6
- "files": ["dist"],
6
+ "files": [
7
+ "dist"
8
+ ],
7
9
  "bin": {
8
10
  "channel": "./dist/index.js",
9
11
  "inerrata-channel": "./dist/index.js",