claude-live 0.4.8 → 1.1.1
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/bin/claude-live.js +36 -20
- package/package.json +13 -26
- package/.claude-plugin/hooks/hooks.json +0 -126
- package/.claude-plugin/marketplace.json +0 -27
- package/.claude-plugin/plugin.json +0 -14
- package/README.md +0 -60
- package/bin/check-and-restart.js +0 -63
- package/bin/send-hook.sh +0 -34
- package/bin/start-server.sh +0 -33
- package/client/dist/assets/index-B1BUdq7a.js +0 -47
- package/client/dist/assets/index-DjcKbX6b.css +0 -1
- package/client/dist/chords/chord_01.wav +0 -0
- package/client/dist/chords/chord_02.wav +0 -0
- package/client/dist/chords/chord_03.wav +0 -0
- package/client/dist/chords/chord_04.wav +0 -0
- package/client/dist/chords/chord_05.wav +0 -0
- package/client/dist/chords/chord_06.wav +0 -0
- package/client/dist/chords/chord_07.wav +0 -0
- package/client/dist/chords/chord_08.wav +0 -0
- package/client/dist/chords/chord_09.wav +0 -0
- package/client/dist/chords/chord_10.wav +0 -0
- package/client/dist/chords/chord_11.wav +0 -0
- package/client/dist/chords/chord_12.wav +0 -0
- package/client/dist/chords/chord_13.wav +0 -0
- package/client/dist/chords/chord_14.wav +0 -0
- package/client/dist/chords/chord_15.wav +0 -0
- package/client/dist/chords/chord_16.wav +0 -0
- package/client/dist/index.html +0 -18
- package/client/public/chords/chord_01.wav +0 -0
- package/client/public/chords/chord_02.wav +0 -0
- package/client/public/chords/chord_03.wav +0 -0
- package/client/public/chords/chord_04.wav +0 -0
- package/client/public/chords/chord_05.wav +0 -0
- package/client/public/chords/chord_06.wav +0 -0
- package/client/public/chords/chord_07.wav +0 -0
- package/client/public/chords/chord_08.wav +0 -0
- package/client/public/chords/chord_09.wav +0 -0
- package/client/public/chords/chord_10.wav +0 -0
- package/client/public/chords/chord_11.wav +0 -0
- package/client/public/chords/chord_12.wav +0 -0
- package/client/public/chords/chord_13.wav +0 -0
- package/client/public/chords/chord_14.wav +0 -0
- package/client/public/chords/chord_15.wav +0 -0
- package/client/public/chords/chord_16.wav +0 -0
- package/commands/claude-live.md +0 -145
- package/hooks/hooks.json +0 -166
- package/server/index.js +0 -288
- package/test-agent-animations-long.js +0 -144
- package/test-agent-animations.js +0 -126
- package/test-agents.js +0 -61
- package/tests/server.test.js +0 -48
- package/tests/store.test.ts +0 -141
- package/vitest.config.ts +0 -10
|
@@ -1 +0,0 @@
|
|
|
1
|
-
@import"https://fonts.googleapis.com/css2?family=Fira+Code:wght@300;400;500&family=Space+Mono:wght@400;700&display=swap";*{margin:0;padding:0;box-sizing:border-box}html,body,#root{width:100%;height:100%;overflow:hidden;background:#050507}#root{position:relative}#root:before{content:"";position:fixed;top:0;right:0;bottom:0;left:0;background-image:url("data:image/svg+xml,%3Csvg viewBox='0 0 200 200' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='noise'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23noise)' opacity='1'/%3E%3C/svg%3E");background-size:150px;opacity:.035;pointer-events:none;z-index:10}.hud{position:fixed;top:24px;left:24px;z-index:20;font-family:Space Mono,monospace;pointer-events:none}.hud-title{font-size:17px;font-weight:700;color:#fff;letter-spacing:-.5px;margin-bottom:14px;line-height:1}.hud-title span{color:#4ade80}.hud-stat{display:flex;align-items:baseline;gap:8px;margin-bottom:5px}.hud-label{font-size:9px;color:#666;text-transform:uppercase;letter-spacing:1px;width:52px}.hud-value{font-size:13px;color:#ccc}.hud-tool{font-weight:700}.tooltip{position:fixed;z-index:30;background:#08080ef0;border:1px solid rgba(255,255,255,.12);border-radius:6px;padding:10px 14px;pointer-events:none;transition:opacity .1s ease;-webkit-backdrop-filter:blur(16px);backdrop-filter:blur(16px);min-width:160px;box-shadow:0 8px 32px #000000b3}.tooltip-label{font-family:Fira Code,monospace;font-size:12px;color:#fff;font-weight:500;margin-bottom:2px;white-space:nowrap;max-width:260px;overflow:hidden;text-overflow:ellipsis}.tooltip-type{font-family:Space Mono,monospace;font-size:9px;color:#888;text-transform:uppercase;letter-spacing:1px;margin-bottom:7px}.tooltip-meta{font-family:Space Mono,monospace;font-size:10px;color:#aaa;margin-bottom:3px}.tooltip-count{font-family:Space Mono,monospace;font-size:9px;color:#666}.sidebar{position:fixed;right:0;top:0;height:100%;width:280px;background:#06060bf5;border-left:1px solid rgba(255,255,255,.08);z-index:25;transform:translate(100%);transition:transform .25s cubic-bezier(.16,1,.3,1);-webkit-backdrop-filter:blur(24px);backdrop-filter:blur(24px);display:flex;flex-direction:column;overflow:hidden}.sidebar--open{transform:translate(0)}.sidebar-header{padding:24px 20px 16px;border-bottom:1px solid rgba(255,255,255,.06);position:relative}.sidebar-close{position:absolute;top:20px;right:16px;width:26px;height:26px;display:flex;align-items:center;justify-content:center;color:#666;cursor:pointer;font-size:18px;border-radius:4px;transition:color .15s,background .15s;pointer-events:all;line-height:1}.sidebar-close:hover{color:#fff;background:#ffffff14}.sidebar-title{font-family:Fira Code,monospace;font-size:13px;color:#fff;font-weight:500;margin-bottom:4px;padding-right:32px;word-break:break-all}.sidebar-type{font-family:Space Mono,monospace;font-size:9px;color:#666;text-transform:uppercase;letter-spacing:1px}.sidebar-section{padding:16px 20px;border-bottom:1px solid rgba(255,255,255,.05)}.sidebar-section-label{font-family:Space Mono,monospace;font-size:9px;color:#555;text-transform:uppercase;letter-spacing:1px;margin-bottom:8px}.sidebar-action{font-family:Fira Code,monospace;font-size:15px;font-weight:500;margin-bottom:3px}.sidebar-time{font-family:Space Mono,monospace;font-size:10px;color:#777}.sidebar-count{font-family:Space Mono,monospace;font-size:24px;color:#ccc;font-weight:700}.sidebar-session{font-family:Fira Code,monospace;font-size:11px;color:#4ade80}.perm-badge{display:inline-flex;align-items:center;gap:5px;font-family:Space Mono,monospace;font-size:9px;color:#fbbf24;background:#fbbf241a;border:1px solid rgba(251,191,36,.3);border-radius:3px;padding:2px 6px;margin-top:6px}.perm-dot{width:5px;height:5px;border-radius:50%;background:#fbbf24;animation:perm-pulse 1s ease-in-out infinite}@keyframes perm-pulse{0%,to{opacity:1;transform:scale(1)}50%{opacity:.4;transform:scale(.7)}}.bottom-left-panel{position:fixed;bottom:24px;left:24px;z-index:20;display:flex;flex-direction:column;gap:10px;pointer-events:none}.bottom-left-panel>*{pointer-events:all}.event-log{display:flex;flex-direction:column;gap:5px;max-width:250px}.event-log-entry{display:flex;align-items:center;gap:5px;position:relative;overflow:hidden;animation:log-entry-in .38s cubic-bezier(.16,1,.3,1)}.event-log-entry:after{content:"";position:absolute;top:0;bottom:0;left:-60%;width:60%;background:linear-gradient(90deg,transparent 0%,var(--entry-color, #888) 60%,transparent 100%);opacity:.22;animation:log-scan .55s ease-out forwards;pointer-events:none}@keyframes log-entry-in{0%{opacity:0;transform:translate(-16px)}55%{opacity:1;transform:translate(3px)}78%{transform:translate(-1px)}to{opacity:1;transform:translate(0)}}@keyframes log-scan{0%{left:-60%;opacity:.22}to{left:130%;opacity:0}}.event-log-dot{width:5px;height:5px;border-radius:50%;flex-shrink:0;animation:log-dot-pop .42s cubic-bezier(.34,1.56,.64,1)}@keyframes log-dot-pop{0%{transform:scale(0) rotate(-90deg)}70%{transform:scale(1.5) rotate(8deg)}to{transform:scale(1) rotate(0)}}.event-log-tool{font-family:Space Mono,monospace;font-size:8px;font-weight:700;min-width:38px;text-transform:uppercase;letter-spacing:.04em;animation:log-tool-in .3s ease-out}@keyframes log-tool-in{0%{opacity:0;letter-spacing:.28em}to{opacity:1;letter-spacing:.04em}}.event-log-file{font-family:Fira Code,monospace;font-size:8px;color:#999;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:100px}.event-log-session{font-family:Fira Code,monospace;font-size:7px;color:#3a3a3a;white-space:nowrap;margin-left:auto}.event-log-entry--static,.event-log-entry--static .event-log-dot,.event-log-entry--static .event-log-tool{animation:none}.event-log-entry--static:after{display:none}.event-log-history{width:280px;height:calc(100vh - 80px);overflow-y:scroll;display:flex;flex-direction:column;gap:5px;background:#020209eb;border:1px solid rgba(255,255,255,.08);border-radius:4px;padding:6px;box-sizing:border-box}.event-log-history-back{font-family:Space Mono,monospace;font-size:8px;color:#555;background:none;border:none;cursor:pointer;text-align:left;padding:0 0 4px}.event-log-history-back:hover{color:#aaa}.event-log-history-btn{font-family:Space Mono,monospace;font-size:7px;color:#333;background:none;border:none;cursor:pointer;text-align:left;padding:2px 0 0 10px}.event-log-history-btn:hover{color:#777}.help-btn{background:none;border:1px solid rgba(255,255,255,.1);border-radius:4px;color:#444;font-family:Space Mono,monospace;font-size:9px;padding:3px 8px;cursor:pointer;width:fit-content;transition:color .15s,border-color .15s;letter-spacing:.05em;text-transform:uppercase}.help-btn:hover{color:#999;border-color:#ffffff40}.top-right-buttons{position:fixed;top:24px;right:24px;z-index:50;display:flex;gap:8px;align-items:center;pointer-events:auto}.audio-toggle{background:none;border:1px solid rgba(255,255,255,.1);border-radius:4px;color:#666;cursor:pointer;transition:color .15s,border-color .15s,background-color .15s;display:flex;align-items:center;justify-content:center;width:32px;height:32px;padding:0;font-size:0}.audio-toggle svg{width:16px;height:16px;stroke:currentColor}.audio-toggle:hover{color:#999;border-color:#ffffff40;background-color:#ffffff0d}.audio-toggle:active{background-color:#ffffff1a}.autofit-toggle{background:none;border:1px solid rgba(255,255,255,.1);color:#ccc;cursor:pointer;display:inline-flex;align-items:center;justify-content:center;border-radius:4px;transition:all .2s ease;width:32px;height:32px;padding:0;font-size:0}.autofit-toggle svg{width:16px;height:16px;stroke:currentColor}.autofit-toggle:hover{color:#999;border-color:#ffffff40;background-color:#ffffff0d}.autofit-toggle:active{background-color:#ffffff1a}.hud-button{width:32px;height:32px;background:#ffffff14;border:1px solid rgba(255,255,255,.12);border-radius:4px;color:#666;cursor:pointer;font-size:14px;display:flex;align-items:center;justify-content:center;transition:color .2s}.hud-button:hover{color:#aaa}.help-overlay{position:fixed;top:0;right:0;bottom:0;left:0;z-index:60;background:#0000008c;display:flex;align-items:center;justify-content:center;-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px)}.help-panel{background:#08080efa;border:1px solid rgba(255,255,255,.1);border-radius:8px;padding:20px 24px;min-width:200px;box-shadow:0 16px 48px #000c}.help-panel-header{display:flex;align-items:center;justify-content:space-between;margin-bottom:14px}.help-panel-title{font-family:Space Mono,monospace;font-size:9px;color:#555;text-transform:uppercase;letter-spacing:1.5px}.legend-title{font-size:8px;color:#444;text-transform:uppercase;letter-spacing:1.5px;margin-bottom:8px}.legend-items{display:flex;flex-direction:column;gap:5px}.legend-item{display:flex;align-items:center;gap:8px}.legend-dot{width:8px;height:8px;border-radius:50%;flex-shrink:0}.legend-badge{width:14px;height:14px;border-radius:50%;display:flex;align-items:center;justify-content:center;font-size:7px;font-weight:700;color:#000;flex-shrink:0}.legend-name{font-size:9px;color:#888}.legend-key{font-size:8px;color:#555;margin-left:auto;padding-left:8px}.legend-perm{display:flex;align-items:center;gap:8px;margin-top:4px;padding-top:6px;border-top:1px solid rgba(255,255,255,.04)}.legend-perm-ring{width:14px;height:14px;border-radius:50%;border:2px dashed #fbbf24;flex-shrink:0}.legend-perm-name{font-size:9px;color:#fbbf24}.debug-toggle{position:fixed;bottom:24px;right:24px;z-index:40;background:#fbbf241f;border:1px solid rgba(251,191,36,.4);border-radius:5px;color:#fbbf24e6;font-family:Space Mono,monospace;font-size:10px;font-weight:700;letter-spacing:.15em;padding:6px 12px;cursor:pointer;transition:color .15s,background .15s,border-color .15s}.debug-toggle:hover{background:#fbbf2438;border-color:#fbbf24b3;color:#fbbf24}.debug-panel{position:fixed;bottom:56px;right:24px;width:260px;background:#06060cf7;border:1px solid rgba(255,255,255,.1);border-radius:8px;z-index:40;-webkit-backdrop-filter:blur(20px);backdrop-filter:blur(20px);box-shadow:0 16px 48px #000c;transform:translateY(8px) scale(.97);opacity:0;pointer-events:none;transition:opacity .18s ease,transform .18s ease}.debug-panel--open{opacity:1;transform:translateY(0) scale(1);pointer-events:all}.debug-panel-header{display:flex;align-items:center;justify-content:space-between;padding:12px 14px 10px;border-bottom:1px solid rgba(255,255,255,.07)}.debug-panel-title{font-family:Space Mono,monospace;font-size:9px;color:#555;text-transform:uppercase;letter-spacing:1.5px}.debug-close{background:none;border:none;color:#555;font-size:16px;cursor:pointer;padding:0 2px;line-height:1;transition:color .15s}.debug-close:hover{color:#ccc}.debug-section{padding:10px 14px;border-bottom:1px solid rgba(255,255,255,.05)}.debug-section:last-child{border-bottom:none}.debug-section-label{font-family:Space Mono,monospace;font-size:8px;color:#444;text-transform:uppercase;letter-spacing:1.5px;margin-bottom:8px}.debug-session-row{display:flex;gap:6px}.debug-select{flex:1;background:#ffffff0d;border:1px solid rgba(255,255,255,.1);border-radius:4px;color:#aaa;font-family:Fira Code,monospace;font-size:10px;padding:4px 7px;outline:none;cursor:pointer}.debug-new-btn{background:#ffffff0f;border:1px solid rgba(255,255,255,.12);border-radius:4px;color:#888;font-family:Space Mono,monospace;font-size:9px;padding:4px 8px;cursor:pointer;white-space:nowrap;transition:color .15s,background .15s}.debug-new-btn:hover{color:#ccc;background:#ffffff1a}.debug-tool-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:5px}.debug-tool-btn{background:#ffffff0a;border:1px solid rgba(255,255,255,.08);border-radius:4px;color:var(--tool-color, #888);font-family:Space Mono,monospace;font-size:9px;padding:6px 4px;cursor:pointer;transition:background .15s,border-color .15s,opacity .15s;text-align:center}.debug-tool-btn:hover{background:color-mix(in srgb,var(--tool-color, #888) 15%,transparent);border-color:color-mix(in srgb,var(--tool-color, #888) 40%,transparent)}.debug-tool-btn:active{opacity:.6}.perm-notifications{position:fixed;left:24px;top:130px;display:flex;flex-direction:column;gap:6px;z-index:100;pointer-events:none;max-width:280px}.perm-notifications-title{font-size:9px;letter-spacing:.2em;text-transform:uppercase;color:#fbbf24;text-align:left;margin-bottom:2px;opacity:.7}.perm-notification-item{display:flex;align-items:flex-start;gap:10px;background:#fbbf240f;border:1px solid rgba(251,191,36,.25);border-radius:3px;padding:8px 14px;animation:perm-fadein .3s ease}@keyframes perm-fadein{0%{opacity:0;transform:translateY(6px)}to{opacity:1;transform:translateY(0)}}.perm-notification-dot{width:6px;height:6px;border-radius:50%;background:#fbbf24;margin-top:3px;flex-shrink:0;animation:perm-pulse 1s ease-in-out infinite}.perm-notification-body{display:flex;flex-direction:column;gap:2px}.perm-notification-session{font-size:9px;letter-spacing:.15em;color:#fbbf2499;text-transform:uppercase}.perm-notification-msg{font-size:11px;color:#fbbf24e6;max-width:320px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.panel-overlay{position:fixed;top:24px;right:24px;max-width:400px;max-height:calc(100vh - 48px);background:#020209f2;border:1px solid rgba(255,255,255,.1);border-radius:8px;padding:16px;overflow-y:auto;z-index:100;font-size:12px;line-height:1.6;color:#ccc}.panel-close,.panel-close-btn{position:absolute;top:8px;right:8px;background:none;border:none;color:#666;cursor:pointer;font-size:16px;padding:0;width:24px;height:24px}.panel-close:hover,.panel-close-btn:hover{color:#aaa}.panel-overlay h3{margin:0 0 12px;font-size:14px;font-weight:600;color:#fff}.panel-overlay h4{margin:8px 0 6px;font-size:12px;font-weight:600;color:#aaa;text-transform:uppercase;letter-spacing:.05em}.panel-section{margin-bottom:16px}.panel-section:last-child{margin-bottom:0}.node-types-grid{display:flex;flex-direction:column;gap:8px}.node-type-item{display:flex;align-items:center;gap:8px}.node-type-badge{width:28px;height:28px;border-radius:4px;display:flex;align-items:center;justify-content:center;font-size:11px;font-weight:600;color:#fff;flex-shrink:0}.node-type-info{display:flex;flex-direction:column;gap:2px}.node-type-name{font-size:12px;font-weight:500;color:#fff}.node-type-description{font-size:10px;color:#888}.animations-list{display:flex;flex-direction:column;gap:10px}.animation-item{font-size:11px}.animation-name{font-weight:500;color:#fff;margin-bottom:2px}.animation-description{font-size:10px;color:#888;padding-left:8px;border-left:2px solid rgba(255,255,255,.1)}
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/client/dist/index.html
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
<!DOCTYPE html>
|
|
2
|
-
<html lang="en">
|
|
3
|
-
<head>
|
|
4
|
-
<meta charset="UTF-8" />
|
|
5
|
-
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
|
-
<title>claude-live</title>
|
|
7
|
-
<style>
|
|
8
|
-
* { margin: 0; padding: 0; box-sizing: border-box; }
|
|
9
|
-
body { background: #080808; overflow: hidden; }
|
|
10
|
-
#root { width: 100vw; height: 100vh; }
|
|
11
|
-
</style>
|
|
12
|
-
<script type="module" crossorigin src="/assets/index-B1BUdq7a.js"></script>
|
|
13
|
-
<link rel="stylesheet" crossorigin href="/assets/index-DjcKbX6b.css">
|
|
14
|
-
</head>
|
|
15
|
-
<body>
|
|
16
|
-
<div id="root"></div>
|
|
17
|
-
</body>
|
|
18
|
-
</html>
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/commands/claude-live.md
DELETED
|
@@ -1,145 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
allowed-tools: Bash(pkill:*), Bash(curl:*), Bash(npx:*), Bash(ps:*), Bash(tail:*), Bash(grep:*), Bash(sed:*), Bash(mkdir:*), Bash(rm:*), Bash(cat:*)
|
|
3
|
-
description: Control and inspect the claude-live visualizer server
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
Manage the claude-live server. The server always runs on port 43451.
|
|
7
|
-
|
|
8
|
-
User's argument: $ARGUMENTS
|
|
9
|
-
|
|
10
|
-
## Subcommands
|
|
11
|
-
|
|
12
|
-
- **no argument / status**: Run the status checks below and display results
|
|
13
|
-
- **stop**: Run `pkill -f "node.*claude-live"` and confirm stopped
|
|
14
|
-
- **start**: Start with `npx claude-live@latest >/tmp/claude-live.log 2>&1 &`, wait 1s, then show status
|
|
15
|
-
- **restart**: Stop then start
|
|
16
|
-
- **logs**: Show `tail -30 /tmp/claude-live.log`
|
|
17
|
-
- **config**: Display current endpoint URL (shows which config source is active)
|
|
18
|
-
- **config `<url>`**: Set global endpoint URL, auto-create `~/.config/claude-live/` if needed
|
|
19
|
-
- **config reset**: Reset to default endpoint (`http://localhost:43451`), delete global config file
|
|
20
|
-
|
|
21
|
-
## Status output (default and after start)
|
|
22
|
-
|
|
23
|
-
Run these and display in a compact summary:
|
|
24
|
-
|
|
25
|
-
```
|
|
26
|
-
curl -sf http://localhost:43451/buffer >/dev/null 2>&1 && echo "● running on port 43451 — http://localhost:43451" || echo "○ stopped"
|
|
27
|
-
ps -eo pid,etime,cmd | grep "node.*claude-live" | grep -v grep
|
|
28
|
-
tail -5 /tmp/claude-live.log 2>/dev/null
|
|
29
|
-
```
|
|
30
|
-
|
|
31
|
-
Show: running/stopped, port (always 43451), PID and uptime if running, last 5 log lines.
|
|
32
|
-
|
|
33
|
-
## Config Management
|
|
34
|
-
|
|
35
|
-
The `/claude-live config` subcommands manage where hooks send events.
|
|
36
|
-
|
|
37
|
-
### Display current URL
|
|
38
|
-
```
|
|
39
|
-
/claude-live config
|
|
40
|
-
```
|
|
41
|
-
Output example: `● Configured: http://192.168.1.50:43451 (from global config)`
|
|
42
|
-
|
|
43
|
-
Possible sources shown:
|
|
44
|
-
- "from environment (CLAUDE_LIVE_URL)"
|
|
45
|
-
- "from project config (.claude/claude-live.json)"
|
|
46
|
-
- "from global config (~/.config/claude-live/config.json)"
|
|
47
|
-
- "default (localhost:43451)"
|
|
48
|
-
|
|
49
|
-
### Set global URL
|
|
50
|
-
```
|
|
51
|
-
/claude-live config http://192.168.1.50:43451
|
|
52
|
-
```
|
|
53
|
-
Output: `✓ URL set to http://192.168.1.50:43451`
|
|
54
|
-
|
|
55
|
-
Behavior:
|
|
56
|
-
- Validates URL format (must start with http:// or https://)
|
|
57
|
-
- Auto-creates `~/.config/claude-live/` directory if needed
|
|
58
|
-
- Writes to `~/.config/claude-live/config.json`
|
|
59
|
-
- Shows error if validation fails or write fails
|
|
60
|
-
|
|
61
|
-
Valid URLs:
|
|
62
|
-
- `http://example.com`
|
|
63
|
-
- `http://192.168.1.50:9000`
|
|
64
|
-
- `https://api.example.com:443`
|
|
65
|
-
|
|
66
|
-
Invalid URLs:
|
|
67
|
-
- `localhost:43451` (no http://)
|
|
68
|
-
- `http://` (no host)
|
|
69
|
-
- `ftp://example.com` (not http/https)
|
|
70
|
-
|
|
71
|
-
### Reset to default
|
|
72
|
-
```
|
|
73
|
-
/claude-live config reset
|
|
74
|
-
```
|
|
75
|
-
Output: `✓ Reset to default (localhost:43451)`
|
|
76
|
-
|
|
77
|
-
Behavior:
|
|
78
|
-
- Deletes `~/.config/claude-live/config.json` if it exists
|
|
79
|
-
- Doesn't affect project config or env var (those still take precedence if set)
|
|
80
|
-
|
|
81
|
-
## Implementation
|
|
82
|
-
|
|
83
|
-
Parse $ARGUMENTS and execute the appropriate subcommand:
|
|
84
|
-
|
|
85
|
-
```bash
|
|
86
|
-
# Handle config subcommands
|
|
87
|
-
if [[ "$ARGUMENTS" == "config" ]] || [[ "$ARGUMENTS" == config* ]]; then
|
|
88
|
-
if [[ "$ARGUMENTS" == "config reset" ]]; then
|
|
89
|
-
# Reset to default
|
|
90
|
-
rm -f "$HOME/.config/claude-live/config.json"
|
|
91
|
-
echo "✓ Reset to default (localhost:43451)"
|
|
92
|
-
elif [[ "$ARGUMENTS" == "config" ]]; then
|
|
93
|
-
# Display current URL
|
|
94
|
-
URL_SOURCE="default"
|
|
95
|
-
URL="http://localhost:43451"
|
|
96
|
-
|
|
97
|
-
if [ -n "$CLAUDE_LIVE_URL" ]; then
|
|
98
|
-
URL="$CLAUDE_LIVE_URL"
|
|
99
|
-
URL_SOURCE="from environment (CLAUDE_LIVE_URL)"
|
|
100
|
-
elif [ -f ".claude/claude-live.json" ]; then
|
|
101
|
-
PROJECT_URL=$(grep -o '"url" *: *"[^"]*"' .claude/claude-live.json 2>/dev/null | head -1 | sed 's/.*: *"//;s/"//')
|
|
102
|
-
if [ -n "$PROJECT_URL" ]; then
|
|
103
|
-
URL="$PROJECT_URL"
|
|
104
|
-
URL_SOURCE="from project config (.claude/claude-live.json)"
|
|
105
|
-
fi
|
|
106
|
-
elif [ -f "$HOME/.config/claude-live/config.json" ]; then
|
|
107
|
-
GLOBAL_URL=$(grep -o '"url" *: *"[^"]*"' "$HOME/.config/claude-live/config.json" 2>/dev/null | head -1 | sed 's/.*: *"//;s/"//')
|
|
108
|
-
if [ -n "$GLOBAL_URL" ]; then
|
|
109
|
-
URL="$GLOBAL_URL"
|
|
110
|
-
URL_SOURCE="from global config (~/.config/claude-live/config.json)"
|
|
111
|
-
fi
|
|
112
|
-
fi
|
|
113
|
-
|
|
114
|
-
echo "● Configured: $URL ($URL_SOURCE)"
|
|
115
|
-
else
|
|
116
|
-
# Set URL
|
|
117
|
-
NEW_URL="${ARGUMENTS#config }"
|
|
118
|
-
|
|
119
|
-
# Validate URL format
|
|
120
|
-
if ! echo "$NEW_URL" | grep -q '^https\?://[^/]'; then
|
|
121
|
-
echo "✗ Invalid URL format: must start with http:// or https://"
|
|
122
|
-
exit 1
|
|
123
|
-
fi
|
|
124
|
-
|
|
125
|
-
# Create directory
|
|
126
|
-
mkdir -p "$HOME/.config/claude-live/" || {
|
|
127
|
-
echo "✗ Failed to create ~/.config/claude-live/ directory"
|
|
128
|
-
exit 1
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
# Write config
|
|
132
|
-
if ! cat > "$HOME/.config/claude-live/config.json" <<EOF
|
|
133
|
-
{
|
|
134
|
-
"url": "$NEW_URL"
|
|
135
|
-
}
|
|
136
|
-
EOF
|
|
137
|
-
then
|
|
138
|
-
echo "✗ Failed to write config file"
|
|
139
|
-
exit 1
|
|
140
|
-
fi
|
|
141
|
-
|
|
142
|
-
echo "✓ URL set to $NEW_URL"
|
|
143
|
-
fi
|
|
144
|
-
fi
|
|
145
|
-
```
|
package/hooks/hooks.json
DELETED
|
@@ -1,166 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"description": "claude-live hooks — forwards Claude Code events to the visualizer server",
|
|
3
|
-
"hooks": {
|
|
4
|
-
"SessionStart": [{
|
|
5
|
-
"hooks": [
|
|
6
|
-
{
|
|
7
|
-
"type": "command",
|
|
8
|
-
"command": "node \"$(npm root -g)/claude-live/bin/check-and-restart.js\" 2>/dev/null || node \"./node_modules/claude-live/bin/check-and-restart.js\" 2>/dev/null || true",
|
|
9
|
-
"async": true
|
|
10
|
-
},
|
|
11
|
-
{
|
|
12
|
-
"type": "command",
|
|
13
|
-
"command": "curl -sf -X POST 'http://localhost:43451/hook' -H 'Content-Type: application/json' -d @- 2>/dev/null || true",
|
|
14
|
-
"async": true
|
|
15
|
-
}
|
|
16
|
-
]
|
|
17
|
-
}],
|
|
18
|
-
"InstructionsLoaded": [{
|
|
19
|
-
"hooks": [{
|
|
20
|
-
"type": "command",
|
|
21
|
-
"command": "curl -sf -X POST 'http://localhost:43451/hook' -H 'Content-Type: application/json' -d @- 2>/dev/null || true",
|
|
22
|
-
"async": true
|
|
23
|
-
}]
|
|
24
|
-
}],
|
|
25
|
-
"WorktreeCreate": [{
|
|
26
|
-
"hooks": [{
|
|
27
|
-
"type": "command",
|
|
28
|
-
"command": "curl -sf -X POST 'http://localhost:43451/hook' -H 'Content-Type: application/json' -d @- 2>/dev/null || true",
|
|
29
|
-
"async": true
|
|
30
|
-
}]
|
|
31
|
-
}],
|
|
32
|
-
"WorktreeRemove": [{
|
|
33
|
-
"hooks": [{
|
|
34
|
-
"type": "command",
|
|
35
|
-
"command": "curl -sf -X POST 'http://localhost:43451/hook' -H 'Content-Type: application/json' -d @- 2>/dev/null || true",
|
|
36
|
-
"async": true
|
|
37
|
-
}]
|
|
38
|
-
}],
|
|
39
|
-
"PreToolUse": [{
|
|
40
|
-
"hooks": [{
|
|
41
|
-
"type": "command",
|
|
42
|
-
"command": "curl -sf -X POST 'http://localhost:43451/hook' -H 'Content-Type: application/json' -d @- 2>/dev/null || true",
|
|
43
|
-
"async": true
|
|
44
|
-
}]
|
|
45
|
-
}],
|
|
46
|
-
"PostToolUse": [{
|
|
47
|
-
"hooks": [{
|
|
48
|
-
"type": "command",
|
|
49
|
-
"command": "curl -sf -X POST 'http://localhost:43451/hook' -H 'Content-Type: application/json' -d @- 2>/dev/null || true",
|
|
50
|
-
"async": true
|
|
51
|
-
}]
|
|
52
|
-
}],
|
|
53
|
-
"Stop": [{
|
|
54
|
-
"hooks": [{
|
|
55
|
-
"type": "command",
|
|
56
|
-
"command": "curl -sf -X POST 'http://localhost:43451/hook' -H 'Content-Type: application/json' -d @- 2>/dev/null || true",
|
|
57
|
-
"async": true
|
|
58
|
-
}]
|
|
59
|
-
}],
|
|
60
|
-
"Notification": [{
|
|
61
|
-
"hooks": [{
|
|
62
|
-
"type": "command",
|
|
63
|
-
"command": "curl -sf -X POST 'http://localhost:43451/hook' -H 'Content-Type: application/json' -d @- 2>/dev/null || true",
|
|
64
|
-
"async": true
|
|
65
|
-
}]
|
|
66
|
-
}],
|
|
67
|
-
"PermissionRequest": [{
|
|
68
|
-
"hooks": [{
|
|
69
|
-
"type": "command",
|
|
70
|
-
"command": "curl -sf -X POST 'http://localhost:43451/hook' -H 'Content-Type: application/json' -d @- 2>/dev/null || true",
|
|
71
|
-
"async": true
|
|
72
|
-
}]
|
|
73
|
-
}],
|
|
74
|
-
"SubagentStart": [{
|
|
75
|
-
"hooks": [{
|
|
76
|
-
"type": "command",
|
|
77
|
-
"command": "curl -sf -X POST 'http://localhost:43451/hook' -H 'Content-Type: application/json' -d @- 2>/dev/null || true",
|
|
78
|
-
"async": true
|
|
79
|
-
}]
|
|
80
|
-
}],
|
|
81
|
-
"SubagentStop": [{
|
|
82
|
-
"hooks": [{
|
|
83
|
-
"type": "command",
|
|
84
|
-
"command": "curl -sf -X POST 'http://localhost:43451/hook' -H 'Content-Type: application/json' -d @- 2>/dev/null || true",
|
|
85
|
-
"async": true
|
|
86
|
-
}]
|
|
87
|
-
}],
|
|
88
|
-
"SessionEnd": [{
|
|
89
|
-
"hooks": [{
|
|
90
|
-
"type": "command",
|
|
91
|
-
"command": "curl -sf -X POST 'http://localhost:43451/hook' -H 'Content-Type: application/json' -d @- 2>/dev/null || true",
|
|
92
|
-
"async": true
|
|
93
|
-
}]
|
|
94
|
-
}],
|
|
95
|
-
"PostToolUseFailure": [{
|
|
96
|
-
"hooks": [{
|
|
97
|
-
"type": "command",
|
|
98
|
-
"command": "curl -sf -X POST 'http://localhost:43451/hook' -H 'Content-Type: application/json' -d @- 2>/dev/null || true",
|
|
99
|
-
"async": true
|
|
100
|
-
}]
|
|
101
|
-
}],
|
|
102
|
-
"UserPromptSubmit": [{
|
|
103
|
-
"hooks": [{
|
|
104
|
-
"type": "command",
|
|
105
|
-
"command": "curl -sf -X POST 'http://localhost:43451/hook' -H 'Content-Type: application/json' -d @- 2>/dev/null || true",
|
|
106
|
-
"async": true
|
|
107
|
-
}]
|
|
108
|
-
}],
|
|
109
|
-
"PreCompact": [{
|
|
110
|
-
"hooks": [{
|
|
111
|
-
"type": "command",
|
|
112
|
-
"command": "curl -sf -X POST 'http://localhost:43451/hook' -H 'Content-Type: application/json' -d @- 2>/dev/null || true",
|
|
113
|
-
"async": true
|
|
114
|
-
}]
|
|
115
|
-
}],
|
|
116
|
-
"PostCompact": [{
|
|
117
|
-
"hooks": [{
|
|
118
|
-
"type": "command",
|
|
119
|
-
"command": "curl -sf -X POST 'http://localhost:43451/hook' -H 'Content-Type: application/json' -d @- 2>/dev/null || true",
|
|
120
|
-
"async": true
|
|
121
|
-
}]
|
|
122
|
-
}],
|
|
123
|
-
"StopFailure": [{
|
|
124
|
-
"hooks": [{
|
|
125
|
-
"type": "command",
|
|
126
|
-
"command": "curl -sf -X POST 'http://localhost:43451/hook' -H 'Content-Type: application/json' -d @- 2>/dev/null || true",
|
|
127
|
-
"async": true
|
|
128
|
-
}]
|
|
129
|
-
}],
|
|
130
|
-
"TeammateIdle": [{
|
|
131
|
-
"hooks": [{
|
|
132
|
-
"type": "command",
|
|
133
|
-
"command": "curl -sf -X POST 'http://localhost:43451/hook' -H 'Content-Type: application/json' -d @- 2>/dev/null || true",
|
|
134
|
-
"async": true
|
|
135
|
-
}]
|
|
136
|
-
}],
|
|
137
|
-
"TaskCompleted": [{
|
|
138
|
-
"hooks": [{
|
|
139
|
-
"type": "command",
|
|
140
|
-
"command": "curl -sf -X POST 'http://localhost:43451/hook' -H 'Content-Type: application/json' -d @- 2>/dev/null || true",
|
|
141
|
-
"async": true
|
|
142
|
-
}]
|
|
143
|
-
}],
|
|
144
|
-
"ConfigChange": [{
|
|
145
|
-
"hooks": [{
|
|
146
|
-
"type": "command",
|
|
147
|
-
"command": "curl -sf -X POST 'http://localhost:43451/hook' -H 'Content-Type: application/json' -d @- 2>/dev/null || true",
|
|
148
|
-
"async": true
|
|
149
|
-
}]
|
|
150
|
-
}],
|
|
151
|
-
"Elicitation": [{
|
|
152
|
-
"hooks": [{
|
|
153
|
-
"type": "command",
|
|
154
|
-
"command": "curl -sf -X POST 'http://localhost:43451/hook' -H 'Content-Type: application/json' -d @- 2>/dev/null || true",
|
|
155
|
-
"async": true
|
|
156
|
-
}]
|
|
157
|
-
}],
|
|
158
|
-
"ElicitationResult": [{
|
|
159
|
-
"hooks": [{
|
|
160
|
-
"type": "command",
|
|
161
|
-
"command": "curl -sf -X POST 'http://localhost:43451/hook' -H 'Content-Type: application/json' -d @- 2>/dev/null || true",
|
|
162
|
-
"async": true
|
|
163
|
-
}]
|
|
164
|
-
}]
|
|
165
|
-
}
|
|
166
|
-
}
|