@delt/claude-alarm 0.3.2 → 0.3.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.
package/README.md CHANGED
@@ -6,50 +6,18 @@ Monitor and interact with multiple Claude Code sessions from a web dashboard. Ge
6
6
 
7
7
  ## Architecture
8
8
 
9
- ```mermaid
10
- graph LR
11
- subgraph "Your Machine"
12
- CC1["Claude Code<br/>(Session 1)"] --> CS1["Channel Server"]
13
- CC2["Claude Code<br/>(Session 2)"] --> CS2["Channel Server"]
14
- CC3["Claude Code<br/>(Session 3)"] --> CS3["Channel Server"]
15
- end
16
-
17
- CS1 -->|WebSocket| HUB["Hub Server<br/>:7900"]
18
- CS2 -->|WebSocket| HUB
19
- CS3 -->|WebSocket| HUB
20
-
21
- HUB -->|HTTP| DASH["Web Dashboard"]
22
- HUB -->|Toast| NOTIF["Desktop<br/>Notifications"]
23
-
24
- subgraph "Remote Machine (optional)"
25
- CC4["Claude Code<br/>(Session 4)"] --> CS4["Channel Server"]
26
- end
27
- CS4 -->|WebSocket| HUB
28
-
29
- style HUB fill:#7c6aef,stroke:#5a4db8,color:#fff
30
- style DASH fill:#3dd68c,stroke:#22a06b,color:#000
31
- style NOTIF fill:#f5c542,stroke:#d4a72c,color:#000
32
- ```
9
+ <p align="center">
10
+ <img src="docs/architecture.svg" alt="Architecture" width="800">
11
+ </p>
33
12
 
34
13
  ## Features
35
14
 
36
- ```mermaid
37
- graph TD
38
- A["Multi-Session<br/>Monitoring"] --> |"real-time"| B["Session Status<br/>idle · working · waiting"]
39
- A --> |"two-way"| C["Message Exchange<br/>text + markdown + images"]
40
- A --> |"alerts"| D["Desktop Notifications<br/>Windows · macOS · Linux"]
41
- A --> |"security"| E["Token Auth<br/>auto-generated"]
42
- A --> |"theme"| F["Dark / Light Mode"]
43
- A --> |"remote"| G["Multi-Machine<br/>Support"]
44
-
45
- style A fill:#7c6aef,stroke:#5a4db8,color:#fff
46
- style B fill:#60a5fa,stroke:#3b82f6,color:#000
47
- style C fill:#3dd68c,stroke:#22a06b,color:#000
48
- style D fill:#f5c542,stroke:#d4a72c,color:#000
49
- style E fill:#ef4444,stroke:#dc2626,color:#fff
50
- style F fill:#8b8fa3,stroke:#6b7280,color:#fff
51
- style G fill:#a78bfa,stroke:#7c3aed,color:#000
52
- ```
15
+ - **Multi-Session Monitoring** — Real-time session status (idle / working / waiting)
16
+ - **Two-way Messaging** — Text + markdown + image exchange with Claude
17
+ - **Desktop Notifications** Windows / macOS / Linux toast alerts
18
+ - **Token Auth** Auto-generated secure access
19
+ - **Dark / Light Mode** Theme toggle with persistence
20
+ - **Multi-Machine** Remote hub access support
53
21
 
54
22
  ## Quick Start
55
23
 
@@ -84,22 +52,9 @@ Open `http://127.0.0.1:7900` in your browser.
84
52
 
85
53
  ## Message Flow
86
54
 
87
- ```mermaid
88
- sequenceDiagram
89
- participant D as Dashboard
90
- participant H as Hub Server
91
- participant C as Channel Server
92
- participant CC as Claude Code
93
-
94
- D->>H: Send message
95
- H->>C: Forward via WebSocket
96
- C->>CC: MCP Channel notification
97
- CC->>CC: Process & execute
98
- CC->>C: Call reply tool
99
- C->>H: Forward reply
100
- H->>D: Display in chat
101
- H->>H: Desktop notification
102
- ```
55
+ <p align="center">
56
+ <img src="docs/message-flow.svg" alt="Message Flow" width="700">
57
+ </p>
103
58
 
104
59
  ## Dashboard Layout
105
60
 
@@ -195,25 +150,9 @@ Config stored at `~/.claude-alarm/config.json`:
195
150
 
196
151
  ## Remote Access
197
152
 
198
- ```mermaid
199
- graph LR
200
- subgraph "Hub PC"
201
- HUB["Hub Server<br/>0.0.0.0:7900"]
202
- end
203
-
204
- subgraph "Remote PC"
205
- RC["Claude Code"] --> RCS["Channel Server"]
206
- end
207
-
208
- subgraph "Browser (any device)"
209
- DASH["Dashboard"]
210
- end
211
-
212
- RCS -->|"WS + token"| HUB
213
- DASH -->|"HTTP + token"| HUB
214
-
215
- style HUB fill:#7c6aef,stroke:#5a4db8,color:#fff
216
- ```
153
+ <p align="center">
154
+ <img src="docs/remote-access.svg" alt="Remote Access" width="600">
155
+ </p>
217
156
 
218
157
  1. Set host to `0.0.0.0` in `~/.claude-alarm/config.json`
219
158
  2. Open port 7900 in your firewall
@@ -11,10 +11,10 @@
11
11
  --border: #2a2d3a;
12
12
  --text: #e1e4ed;
13
13
  --text-dim: #8b8fa3;
14
- --accent: #7c6aef;
15
- --accent-dim: #5a4db8;
14
+ --accent: #e0a86d;
15
+ --accent-dim: #c48d52;
16
16
  --green: #3dd68c;
17
- --yellow: #f5c542;
17
+ --yellow: #f59e0b;
18
18
  --red: #ef4444;
19
19
  --blue: #60a5fa;
20
20
  }
@@ -24,10 +24,10 @@
24
24
  --border: #d1d5db;
25
25
  --text: #1f2937;
26
26
  --text-dim: #6b7280;
27
- --accent: #7c6aef;
28
- --accent-dim: #5a4db8;
27
+ --accent: #c48d52;
28
+ --accent-dim: #a87642;
29
29
  --green: #22c55e;
30
- --yellow: #eab308;
30
+ --yellow: #d97706;
31
31
  --red: #ef4444;
32
32
  --blue: #3b82f6;
33
33
  }
@@ -142,6 +142,26 @@
142
142
  text-align: center;
143
143
  padding: 40px 20px;
144
144
  }
145
+ .cmd-copy {
146
+ display: flex;
147
+ align-items: center;
148
+ background: var(--bg);
149
+ border: 1px solid var(--border);
150
+ border-radius: 6px;
151
+ padding: 6px 10px;
152
+ margin-top: 12px;
153
+ font-size: 11px;
154
+ font-family: monospace;
155
+ cursor: pointer;
156
+ transition: border-color 0.15s;
157
+ text-align: left;
158
+ gap: 6px;
159
+ }
160
+ .cmd-copy:hover { border-color: var(--accent); }
161
+ .cmd-copy .cmd-text { flex: 1; color: var(--text); word-break: break-all; }
162
+ .cmd-copy .cmd-icon { color: var(--text-dim); font-size: 14px; flex-shrink: 0; }
163
+ .cmd-copy.copied { border-color: var(--green); }
164
+ .cmd-copy.copied .cmd-icon { color: var(--green); }
145
165
 
146
166
  /* Messages panel */
147
167
  .messages-panel {
@@ -172,8 +192,8 @@
172
192
  border: 1px solid var(--border);
173
193
  }
174
194
  .message.from-dashboard {
175
- background: rgba(124,106,239,0.12);
176
- border: 1px solid rgba(124,106,239,0.25);
195
+ background: rgba(224,168,109,0.12);
196
+ border: 1px solid rgba(224,168,109,0.25);
177
197
  margin-left: auto;
178
198
  }
179
199
  .message-meta {
@@ -223,7 +243,7 @@
223
243
  .drag-overlay {
224
244
  position: absolute;
225
245
  inset: 0;
226
- background: rgba(124,106,239,0.15);
246
+ background: rgba(224,168,109,0.15);
227
247
  border: 2px dashed var(--accent);
228
248
  border-radius: 8px;
229
249
  display: none;
@@ -580,7 +600,30 @@
580
600
  const el = $('#sessionsList');
581
601
  const ids = Object.keys(state.sessions);
582
602
  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>';
603
+ el.innerHTML = `<div class="no-sessions">No active sessions.<br>Start Claude Code with the channel:
604
+ <div class="cmd-copy" id="cmdCopy1" title="Click to copy">
605
+ <span class="cmd-text">claude --dangerously-load-development-channels server:claude-alarm</span>
606
+ <span class="cmd-icon">&#128203;</span>
607
+ </div>
608
+ <div style="margin-top:8px;font-size:11px;color:var(--text-dim)">or with auto-approve:</div>
609
+ <div class="cmd-copy" id="cmdCopy2" title="Click to copy">
610
+ <span class="cmd-text">claude --dangerously-load-development-channels server:claude-alarm --dangerously-skip-permissions</span>
611
+ <span class="cmd-icon">&#128203;</span>
612
+ </div>
613
+ </div>`;
614
+ el.querySelectorAll('.cmd-copy').forEach(btn => {
615
+ btn.addEventListener('click', () => {
616
+ const text = btn.querySelector('.cmd-text').textContent;
617
+ navigator.clipboard.writeText(text).then(() => {
618
+ btn.classList.add('copied');
619
+ btn.querySelector('.cmd-icon').innerHTML = '&#10003;';
620
+ setTimeout(() => {
621
+ btn.classList.remove('copied');
622
+ btn.querySelector('.cmd-icon').innerHTML = '&#128203;';
623
+ }, 2000);
624
+ });
625
+ });
626
+ });
584
627
  return;
585
628
  }
586
629
  el.innerHTML = ids.map(id => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@delt/claude-alarm",
3
- "version": "0.3.2",
3
+ "version": "0.3.5",
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",
@@ -11,10 +11,10 @@
11
11
  --border: #2a2d3a;
12
12
  --text: #e1e4ed;
13
13
  --text-dim: #8b8fa3;
14
- --accent: #7c6aef;
15
- --accent-dim: #5a4db8;
14
+ --accent: #e0a86d;
15
+ --accent-dim: #c48d52;
16
16
  --green: #3dd68c;
17
- --yellow: #f5c542;
17
+ --yellow: #f59e0b;
18
18
  --red: #ef4444;
19
19
  --blue: #60a5fa;
20
20
  }
@@ -24,10 +24,10 @@
24
24
  --border: #d1d5db;
25
25
  --text: #1f2937;
26
26
  --text-dim: #6b7280;
27
- --accent: #7c6aef;
28
- --accent-dim: #5a4db8;
27
+ --accent: #c48d52;
28
+ --accent-dim: #a87642;
29
29
  --green: #22c55e;
30
- --yellow: #eab308;
30
+ --yellow: #d97706;
31
31
  --red: #ef4444;
32
32
  --blue: #3b82f6;
33
33
  }
@@ -142,6 +142,26 @@
142
142
  text-align: center;
143
143
  padding: 40px 20px;
144
144
  }
145
+ .cmd-copy {
146
+ display: flex;
147
+ align-items: center;
148
+ background: var(--bg);
149
+ border: 1px solid var(--border);
150
+ border-radius: 6px;
151
+ padding: 6px 10px;
152
+ margin-top: 12px;
153
+ font-size: 11px;
154
+ font-family: monospace;
155
+ cursor: pointer;
156
+ transition: border-color 0.15s;
157
+ text-align: left;
158
+ gap: 6px;
159
+ }
160
+ .cmd-copy:hover { border-color: var(--accent); }
161
+ .cmd-copy .cmd-text { flex: 1; color: var(--text); word-break: break-all; }
162
+ .cmd-copy .cmd-icon { color: var(--text-dim); font-size: 14px; flex-shrink: 0; }
163
+ .cmd-copy.copied { border-color: var(--green); }
164
+ .cmd-copy.copied .cmd-icon { color: var(--green); }
145
165
 
146
166
  /* Messages panel */
147
167
  .messages-panel {
@@ -172,8 +192,8 @@
172
192
  border: 1px solid var(--border);
173
193
  }
174
194
  .message.from-dashboard {
175
- background: rgba(124,106,239,0.12);
176
- border: 1px solid rgba(124,106,239,0.25);
195
+ background: rgba(224,168,109,0.12);
196
+ border: 1px solid rgba(224,168,109,0.25);
177
197
  margin-left: auto;
178
198
  }
179
199
  .message-meta {
@@ -223,7 +243,7 @@
223
243
  .drag-overlay {
224
244
  position: absolute;
225
245
  inset: 0;
226
- background: rgba(124,106,239,0.15);
246
+ background: rgba(224,168,109,0.15);
227
247
  border: 2px dashed var(--accent);
228
248
  border-radius: 8px;
229
249
  display: none;
@@ -580,7 +600,30 @@
580
600
  const el = $('#sessionsList');
581
601
  const ids = Object.keys(state.sessions);
582
602
  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>';
603
+ el.innerHTML = `<div class="no-sessions">No active sessions.<br>Start Claude Code with the channel:
604
+ <div class="cmd-copy" id="cmdCopy1" title="Click to copy">
605
+ <span class="cmd-text">claude --dangerously-load-development-channels server:claude-alarm</span>
606
+ <span class="cmd-icon">&#128203;</span>
607
+ </div>
608
+ <div style="margin-top:8px;font-size:11px;color:var(--text-dim)">or with auto-approve:</div>
609
+ <div class="cmd-copy" id="cmdCopy2" title="Click to copy">
610
+ <span class="cmd-text">claude --dangerously-load-development-channels server:claude-alarm --dangerously-skip-permissions</span>
611
+ <span class="cmd-icon">&#128203;</span>
612
+ </div>
613
+ </div>`;
614
+ el.querySelectorAll('.cmd-copy').forEach(btn => {
615
+ btn.addEventListener('click', () => {
616
+ const text = btn.querySelector('.cmd-text').textContent;
617
+ navigator.clipboard.writeText(text).then(() => {
618
+ btn.classList.add('copied');
619
+ btn.querySelector('.cmd-icon').innerHTML = '&#10003;';
620
+ setTimeout(() => {
621
+ btn.classList.remove('copied');
622
+ btn.querySelector('.cmd-icon').innerHTML = '&#128203;';
623
+ }, 2000);
624
+ });
625
+ });
626
+ });
584
627
  return;
585
628
  }
586
629
  el.innerHTML = ids.map(id => {