@delt/claude-alarm 0.3.4 → 0.3.6

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.
@@ -98,6 +98,10 @@
98
98
  letter-spacing: 0.5px;
99
99
  color: var(--text-dim);
100
100
  padding: 8px 8px 12px;
101
+ position: sticky;
102
+ top: 0;
103
+ background: var(--bg);
104
+ z-index: 1;
101
105
  }
102
106
  .session-card {
103
107
  background: var(--surface);
@@ -142,6 +146,26 @@
142
146
  text-align: center;
143
147
  padding: 40px 20px;
144
148
  }
149
+ .cmd-copy {
150
+ display: flex;
151
+ align-items: center;
152
+ background: var(--bg);
153
+ border: 1px solid var(--border);
154
+ border-radius: 6px;
155
+ padding: 6px 10px;
156
+ margin-top: 12px;
157
+ font-size: 11px;
158
+ font-family: monospace;
159
+ cursor: pointer;
160
+ transition: border-color 0.15s;
161
+ text-align: left;
162
+ gap: 6px;
163
+ }
164
+ .cmd-copy:hover { border-color: var(--accent); }
165
+ .cmd-copy .cmd-text { flex: 1; color: var(--text); word-break: break-all; }
166
+ .cmd-copy .cmd-icon { color: var(--text-dim); font-size: 14px; flex-shrink: 0; }
167
+ .cmd-copy.copied { border-color: var(--green); }
168
+ .cmd-copy.copied .cmd-icon { color: var(--green); }
145
169
 
146
170
  /* Messages panel */
147
171
  .messages-panel {
@@ -187,6 +211,28 @@
187
211
  margin-top: 4px;
188
212
  }
189
213
 
214
+ /* Scroll to bottom button */
215
+ .scroll-bottom {
216
+ position: absolute;
217
+ bottom: 80px;
218
+ right: 30px;
219
+ width: 36px;
220
+ height: 36px;
221
+ border-radius: 50%;
222
+ background: var(--surface);
223
+ border: 1px solid var(--border);
224
+ color: var(--text);
225
+ cursor: pointer;
226
+ font-size: 16px;
227
+ display: none;
228
+ align-items: center;
229
+ justify-content: center;
230
+ z-index: 5;
231
+ transition: border-color 0.15s;
232
+ }
233
+ .scroll-bottom:hover { border-color: var(--accent); }
234
+ .scroll-bottom.visible { display: flex; }
235
+
190
236
  /* Image preview */
191
237
  .image-preview {
192
238
  border-top: 1px solid var(--border);
@@ -294,6 +340,10 @@
294
340
  letter-spacing: 0.5px;
295
341
  color: var(--text-dim);
296
342
  padding: 8px 8px 12px;
343
+ position: sticky;
344
+ top: 0;
345
+ background: var(--bg);
346
+ z-index: 1;
297
347
  }
298
348
  .notif-item {
299
349
  background: var(--surface);
@@ -435,6 +485,7 @@
435
485
  <div class="messages-list" id="messagesList">
436
486
  <div class="empty-state">Select a session to view messages</div>
437
487
  </div>
488
+ <button class="scroll-bottom" id="scrollBottom" title="Scroll to bottom">&#8595;</button>
438
489
  <div class="drag-overlay" id="dragOverlay">Drop image here</div>
439
490
  <div class="image-preview" id="imagePreview">
440
491
  <img id="previewImg" src="" alt="preview">
@@ -580,7 +631,30 @@
580
631
  const el = $('#sessionsList');
581
632
  const ids = Object.keys(state.sessions);
582
633
  if (!ids.length) {
583
- el.innerHTML = '<div class="no-sessions">No active sessions.<br>Start Claude Code with the channel to see sessions here.</div>';
634
+ el.innerHTML = `<div class="no-sessions">No active sessions.<br>Start Claude Code with the channel:
635
+ <div class="cmd-copy" id="cmdCopy1" title="Click to copy">
636
+ <span class="cmd-text">claude --dangerously-load-development-channels server:claude-alarm</span>
637
+ <span class="cmd-icon">&#128203;</span>
638
+ </div>
639
+ <div style="margin-top:8px;font-size:11px;color:var(--text-dim)">or with auto-approve:</div>
640
+ <div class="cmd-copy" id="cmdCopy2" title="Click to copy">
641
+ <span class="cmd-text">claude --dangerously-load-development-channels server:claude-alarm --dangerously-skip-permissions</span>
642
+ <span class="cmd-icon">&#128203;</span>
643
+ </div>
644
+ </div>`;
645
+ el.querySelectorAll('.cmd-copy').forEach(btn => {
646
+ btn.addEventListener('click', () => {
647
+ const text = btn.querySelector('.cmd-text').textContent;
648
+ navigator.clipboard.writeText(text).then(() => {
649
+ btn.classList.add('copied');
650
+ btn.querySelector('.cmd-icon').innerHTML = '&#10003;';
651
+ setTimeout(() => {
652
+ btn.classList.remove('copied');
653
+ btn.querySelector('.cmd-icon').innerHTML = '&#128203;';
654
+ }, 2000);
655
+ });
656
+ });
657
+ });
584
658
  return;
585
659
  }
586
660
  el.innerHTML = ids.map(id => {
@@ -827,6 +901,17 @@
827
901
  return html;
828
902
  }
829
903
 
904
+ // Scroll to bottom button
905
+ const msgList = $('#messagesList');
906
+ const scrollBtn = $('#scrollBottom');
907
+ msgList.addEventListener('scroll', () => {
908
+ const gap = msgList.scrollHeight - msgList.scrollTop - msgList.clientHeight;
909
+ scrollBtn.classList.toggle('visible', gap > 100);
910
+ });
911
+ scrollBtn.addEventListener('click', () => {
912
+ msgList.scrollTo({ top: msgList.scrollHeight, behavior: 'smooth' });
913
+ });
914
+
830
915
  state.token = getToken();
831
916
  connect();
832
917
  })();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@delt/claude-alarm",
3
- "version": "0.3.4",
3
+ "version": "0.3.6",
4
4
  "description": "Monitor and get notifications from multiple Claude Code sessions via MCP Channels",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -98,6 +98,10 @@
98
98
  letter-spacing: 0.5px;
99
99
  color: var(--text-dim);
100
100
  padding: 8px 8px 12px;
101
+ position: sticky;
102
+ top: 0;
103
+ background: var(--bg);
104
+ z-index: 1;
101
105
  }
102
106
  .session-card {
103
107
  background: var(--surface);
@@ -142,6 +146,26 @@
142
146
  text-align: center;
143
147
  padding: 40px 20px;
144
148
  }
149
+ .cmd-copy {
150
+ display: flex;
151
+ align-items: center;
152
+ background: var(--bg);
153
+ border: 1px solid var(--border);
154
+ border-radius: 6px;
155
+ padding: 6px 10px;
156
+ margin-top: 12px;
157
+ font-size: 11px;
158
+ font-family: monospace;
159
+ cursor: pointer;
160
+ transition: border-color 0.15s;
161
+ text-align: left;
162
+ gap: 6px;
163
+ }
164
+ .cmd-copy:hover { border-color: var(--accent); }
165
+ .cmd-copy .cmd-text { flex: 1; color: var(--text); word-break: break-all; }
166
+ .cmd-copy .cmd-icon { color: var(--text-dim); font-size: 14px; flex-shrink: 0; }
167
+ .cmd-copy.copied { border-color: var(--green); }
168
+ .cmd-copy.copied .cmd-icon { color: var(--green); }
145
169
 
146
170
  /* Messages panel */
147
171
  .messages-panel {
@@ -187,6 +211,28 @@
187
211
  margin-top: 4px;
188
212
  }
189
213
 
214
+ /* Scroll to bottom button */
215
+ .scroll-bottom {
216
+ position: absolute;
217
+ bottom: 80px;
218
+ right: 30px;
219
+ width: 36px;
220
+ height: 36px;
221
+ border-radius: 50%;
222
+ background: var(--surface);
223
+ border: 1px solid var(--border);
224
+ color: var(--text);
225
+ cursor: pointer;
226
+ font-size: 16px;
227
+ display: none;
228
+ align-items: center;
229
+ justify-content: center;
230
+ z-index: 5;
231
+ transition: border-color 0.15s;
232
+ }
233
+ .scroll-bottom:hover { border-color: var(--accent); }
234
+ .scroll-bottom.visible { display: flex; }
235
+
190
236
  /* Image preview */
191
237
  .image-preview {
192
238
  border-top: 1px solid var(--border);
@@ -294,6 +340,10 @@
294
340
  letter-spacing: 0.5px;
295
341
  color: var(--text-dim);
296
342
  padding: 8px 8px 12px;
343
+ position: sticky;
344
+ top: 0;
345
+ background: var(--bg);
346
+ z-index: 1;
297
347
  }
298
348
  .notif-item {
299
349
  background: var(--surface);
@@ -435,6 +485,7 @@
435
485
  <div class="messages-list" id="messagesList">
436
486
  <div class="empty-state">Select a session to view messages</div>
437
487
  </div>
488
+ <button class="scroll-bottom" id="scrollBottom" title="Scroll to bottom">&#8595;</button>
438
489
  <div class="drag-overlay" id="dragOverlay">Drop image here</div>
439
490
  <div class="image-preview" id="imagePreview">
440
491
  <img id="previewImg" src="" alt="preview">
@@ -580,7 +631,30 @@
580
631
  const el = $('#sessionsList');
581
632
  const ids = Object.keys(state.sessions);
582
633
  if (!ids.length) {
583
- el.innerHTML = '<div class="no-sessions">No active sessions.<br>Start Claude Code with the channel to see sessions here.</div>';
634
+ el.innerHTML = `<div class="no-sessions">No active sessions.<br>Start Claude Code with the channel:
635
+ <div class="cmd-copy" id="cmdCopy1" title="Click to copy">
636
+ <span class="cmd-text">claude --dangerously-load-development-channels server:claude-alarm</span>
637
+ <span class="cmd-icon">&#128203;</span>
638
+ </div>
639
+ <div style="margin-top:8px;font-size:11px;color:var(--text-dim)">or with auto-approve:</div>
640
+ <div class="cmd-copy" id="cmdCopy2" title="Click to copy">
641
+ <span class="cmd-text">claude --dangerously-load-development-channels server:claude-alarm --dangerously-skip-permissions</span>
642
+ <span class="cmd-icon">&#128203;</span>
643
+ </div>
644
+ </div>`;
645
+ el.querySelectorAll('.cmd-copy').forEach(btn => {
646
+ btn.addEventListener('click', () => {
647
+ const text = btn.querySelector('.cmd-text').textContent;
648
+ navigator.clipboard.writeText(text).then(() => {
649
+ btn.classList.add('copied');
650
+ btn.querySelector('.cmd-icon').innerHTML = '&#10003;';
651
+ setTimeout(() => {
652
+ btn.classList.remove('copied');
653
+ btn.querySelector('.cmd-icon').innerHTML = '&#128203;';
654
+ }, 2000);
655
+ });
656
+ });
657
+ });
584
658
  return;
585
659
  }
586
660
  el.innerHTML = ids.map(id => {
@@ -827,6 +901,17 @@
827
901
  return html;
828
902
  }
829
903
 
904
+ // Scroll to bottom button
905
+ const msgList = $('#messagesList');
906
+ const scrollBtn = $('#scrollBottom');
907
+ msgList.addEventListener('scroll', () => {
908
+ const gap = msgList.scrollHeight - msgList.scrollTop - msgList.clientHeight;
909
+ scrollBtn.classList.toggle('visible', gap > 100);
910
+ });
911
+ scrollBtn.addEventListener('click', () => {
912
+ msgList.scrollTo({ top: msgList.scrollHeight, behavior: 'smooth' });
913
+ });
914
+
830
915
  state.token = getToken();
831
916
  connect();
832
917
  })();