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.
Files changed (53) hide show
  1. package/bin/claude-live.js +36 -20
  2. package/package.json +13 -26
  3. package/.claude-plugin/hooks/hooks.json +0 -126
  4. package/.claude-plugin/marketplace.json +0 -27
  5. package/.claude-plugin/plugin.json +0 -14
  6. package/README.md +0 -60
  7. package/bin/check-and-restart.js +0 -63
  8. package/bin/send-hook.sh +0 -34
  9. package/bin/start-server.sh +0 -33
  10. package/client/dist/assets/index-B1BUdq7a.js +0 -47
  11. package/client/dist/assets/index-DjcKbX6b.css +0 -1
  12. package/client/dist/chords/chord_01.wav +0 -0
  13. package/client/dist/chords/chord_02.wav +0 -0
  14. package/client/dist/chords/chord_03.wav +0 -0
  15. package/client/dist/chords/chord_04.wav +0 -0
  16. package/client/dist/chords/chord_05.wav +0 -0
  17. package/client/dist/chords/chord_06.wav +0 -0
  18. package/client/dist/chords/chord_07.wav +0 -0
  19. package/client/dist/chords/chord_08.wav +0 -0
  20. package/client/dist/chords/chord_09.wav +0 -0
  21. package/client/dist/chords/chord_10.wav +0 -0
  22. package/client/dist/chords/chord_11.wav +0 -0
  23. package/client/dist/chords/chord_12.wav +0 -0
  24. package/client/dist/chords/chord_13.wav +0 -0
  25. package/client/dist/chords/chord_14.wav +0 -0
  26. package/client/dist/chords/chord_15.wav +0 -0
  27. package/client/dist/chords/chord_16.wav +0 -0
  28. package/client/dist/index.html +0 -18
  29. package/client/public/chords/chord_01.wav +0 -0
  30. package/client/public/chords/chord_02.wav +0 -0
  31. package/client/public/chords/chord_03.wav +0 -0
  32. package/client/public/chords/chord_04.wav +0 -0
  33. package/client/public/chords/chord_05.wav +0 -0
  34. package/client/public/chords/chord_06.wav +0 -0
  35. package/client/public/chords/chord_07.wav +0 -0
  36. package/client/public/chords/chord_08.wav +0 -0
  37. package/client/public/chords/chord_09.wav +0 -0
  38. package/client/public/chords/chord_10.wav +0 -0
  39. package/client/public/chords/chord_11.wav +0 -0
  40. package/client/public/chords/chord_12.wav +0 -0
  41. package/client/public/chords/chord_13.wav +0 -0
  42. package/client/public/chords/chord_14.wav +0 -0
  43. package/client/public/chords/chord_15.wav +0 -0
  44. package/client/public/chords/chord_16.wav +0 -0
  45. package/commands/claude-live.md +0 -145
  46. package/hooks/hooks.json +0 -166
  47. package/server/index.js +0 -288
  48. package/test-agent-animations-long.js +0 -144
  49. package/test-agent-animations.js +0 -126
  50. package/test-agents.js +0 -61
  51. package/tests/server.test.js +0 -48
  52. package/tests/store.test.ts +0 -141
  53. 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
@@ -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
@@ -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
- }