claude-live 0.1.0 → 0.4.0

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 (47) hide show
  1. package/.claude-plugin/hooks/hooks.json +123 -34
  2. package/.claude-plugin/marketplace.json +29 -0
  3. package/.claude-plugin/plugin.json +2 -3
  4. package/bin/claude-live.js +15 -18
  5. package/bin/send-hook.sh +34 -0
  6. package/bin/start-server.sh +33 -0
  7. package/client/dist/assets/index-C2EVAfon.js +47 -0
  8. package/client/dist/assets/index-DMfuaPRG.css +1 -0
  9. package/client/dist/chords/chord_01.wav +0 -0
  10. package/client/dist/chords/chord_02.wav +0 -0
  11. package/client/dist/chords/chord_03.wav +0 -0
  12. package/client/dist/chords/chord_04.wav +0 -0
  13. package/client/dist/chords/chord_05.wav +0 -0
  14. package/client/dist/chords/chord_06.wav +0 -0
  15. package/client/dist/chords/chord_07.wav +0 -0
  16. package/client/dist/chords/chord_08.wav +0 -0
  17. package/client/dist/chords/chord_09.wav +0 -0
  18. package/client/dist/chords/chord_10.wav +0 -0
  19. package/client/dist/chords/chord_11.wav +0 -0
  20. package/client/dist/chords/chord_12.wav +0 -0
  21. package/client/dist/chords/chord_13.wav +0 -0
  22. package/client/dist/chords/chord_14.wav +0 -0
  23. package/client/dist/chords/chord_15.wav +0 -0
  24. package/client/dist/chords/chord_16.wav +0 -0
  25. package/client/dist/index.html +2 -4
  26. package/client/public/chords/chord_01.wav +0 -0
  27. package/client/public/chords/chord_02.wav +0 -0
  28. package/client/public/chords/chord_03.wav +0 -0
  29. package/client/public/chords/chord_04.wav +0 -0
  30. package/client/public/chords/chord_05.wav +0 -0
  31. package/client/public/chords/chord_06.wav +0 -0
  32. package/client/public/chords/chord_07.wav +0 -0
  33. package/client/public/chords/chord_08.wav +0 -0
  34. package/client/public/chords/chord_09.wav +0 -0
  35. package/client/public/chords/chord_10.wav +0 -0
  36. package/client/public/chords/chord_11.wav +0 -0
  37. package/client/public/chords/chord_12.wav +0 -0
  38. package/client/public/chords/chord_13.wav +0 -0
  39. package/client/public/chords/chord_14.wav +0 -0
  40. package/client/public/chords/chord_15.wav +0 -0
  41. package/client/public/chords/chord_16.wav +0 -0
  42. package/commands/claude-live.md +145 -0
  43. package/hooks/hooks.json +124 -0
  44. package/package.json +7 -3
  45. package/server/index.js +61 -10
  46. package/client/dist/assets/index-BXJC63mX.css +0 -1
  47. package/client/dist/assets/index-ChC1TyfG.js +0 -40
@@ -1,37 +1,126 @@
1
1
  {
2
- "PreToolUse": [{
3
- "hooks": [{
4
- "type": "command",
5
- "command": "curl -sf -X POST http://localhost:43451/hook -H 'Content-Type: application/json' -d @- 2>/dev/null || true",
6
- "async": true
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": "curl -sf http://localhost:43451/buffer >/dev/null 2>&1 || (npx claude-live@latest >/tmp/claude-live.log 2>&1 &)",
9
+ "async": true
10
+ },
11
+ {
12
+ "type": "command",
13
+ "command": "bin/send-hook.sh",
14
+ "async": true
15
+ }
16
+ ]
17
+ }],
18
+ "InstructionsLoaded": [{
19
+ "hooks": [{
20
+ "type": "command",
21
+ "command": "bin/send-hook.sh",
22
+ "async": true
23
+ }]
24
+ }],
25
+ "WorktreeCreate": [{
26
+ "hooks": [{
27
+ "type": "command",
28
+ "command": "bin/send-hook.sh",
29
+ "async": true
30
+ }]
31
+ }],
32
+ "WorktreeRemove": [{
33
+ "hooks": [{
34
+ "type": "command",
35
+ "command": "bin/send-hook.sh",
36
+ "async": true
37
+ }]
38
+ }],
39
+ "PreToolUse": [{
40
+ "hooks": [{
41
+ "type": "command",
42
+ "command": "bin/send-hook.sh",
43
+ "async": true
44
+ }]
45
+ }],
46
+ "PostToolUse": [{
47
+ "hooks": [{
48
+ "type": "command",
49
+ "command": "bin/send-hook.sh",
50
+ "async": true
51
+ }]
52
+ }],
53
+ "Stop": [{
54
+ "hooks": [{
55
+ "type": "command",
56
+ "command": "bin/send-hook.sh",
57
+ "async": true
58
+ }]
59
+ }],
60
+ "Notification": [{
61
+ "hooks": [{
62
+ "type": "command",
63
+ "command": "bin/send-hook.sh",
64
+ "async": true
65
+ }]
66
+ }],
67
+ "PermissionRequest": [{
68
+ "hooks": [{
69
+ "type": "command",
70
+ "command": "bin/send-hook.sh",
71
+ "async": true
72
+ }]
73
+ }],
74
+ "SubagentStart": [{
75
+ "hooks": [{
76
+ "type": "command",
77
+ "command": "bin/send-hook.sh",
78
+ "async": true
79
+ }]
80
+ }],
81
+ "SubagentStop": [{
82
+ "hooks": [{
83
+ "type": "command",
84
+ "command": "bin/send-hook.sh",
85
+ "async": true
86
+ }]
87
+ }],
88
+ "SessionEnd": [{
89
+ "hooks": [{
90
+ "type": "command",
91
+ "command": "bin/send-hook.sh",
92
+ "async": true
93
+ }]
94
+ }],
95
+ "PostToolUseFailure": [{
96
+ "hooks": [{
97
+ "type": "command",
98
+ "command": "bin/send-hook.sh",
99
+ "async": true
100
+ }]
101
+ }],
102
+ "UserPromptSubmit": [{
103
+ "hooks": [{
104
+ "type": "command",
105
+ "command": "bin/send-hook.sh",
106
+ "async": true
107
+ }]
108
+ }],
109
+ "PreCompact": [{
110
+ "match": { "trigger": ["manual", "auto"] },
111
+ "hooks": [{
112
+ "type": "command",
113
+ "command": "bin/send-hook.sh",
114
+ "async": true
115
+ }]
116
+ }],
117
+ "PostCompact": [{
118
+ "match": { "trigger": ["manual", "auto"] },
119
+ "hooks": [{
120
+ "type": "command",
121
+ "command": "bin/send-hook.sh",
122
+ "async": true
123
+ }]
7
124
  }]
8
- }],
9
- "PostToolUse": [{
10
- "hooks": [{
11
- "type": "command",
12
- "command": "curl -sf -X POST http://localhost:43451/hook -H 'Content-Type: application/json' -d @- 2>/dev/null || true",
13
- "async": true
14
- }]
15
- }],
16
- "Stop": [{
17
- "hooks": [{
18
- "type": "command",
19
- "command": "curl -sf -X POST http://localhost:43451/hook -H 'Content-Type: application/json' -d @- 2>/dev/null || true",
20
- "async": true
21
- }]
22
- }],
23
- "Notification": [{
24
- "hooks": [{
25
- "type": "command",
26
- "command": "curl -sf -X POST http://localhost:43451/hook -H 'Content-Type: application/json' -d @- 2>/dev/null || true",
27
- "async": true
28
- }]
29
- }],
30
- "PermissionRequest": [{
31
- "hooks": [{
32
- "type": "command",
33
- "command": "curl -sf -X POST http://localhost:43451/hook -H 'Content-Type: application/json' -d @- 2>/dev/null || true",
34
- "async": true
35
- }]
36
- }]
125
+ }
37
126
  }
@@ -0,0 +1,29 @@
1
+ {
2
+ "name": "claude-live",
3
+ "owner": {
4
+ "name": "marisancans"
5
+ },
6
+ "metadata": {
7
+ "description": "Realtime solar system visualizer for Claude Code sessions",
8
+ "version": "0.2.0"
9
+ },
10
+ "plugins": [
11
+ {
12
+ "name": "claude-live",
13
+ "source": "./",
14
+ "description": "Watch your Claude Code sessions rendered as a living solar system. Files orbit as planets, operations fire directional lasers, parallel sessions glow as separate star clusters.",
15
+ "version": "0.2.0",
16
+ "author": {
17
+ "name": "marisancans"
18
+ },
19
+ "category": "development",
20
+ "keywords": [
21
+ "visualizer",
22
+ "activity",
23
+ "realtime",
24
+ "orbit",
25
+ "solar-system"
26
+ ]
27
+ }
28
+ ]
29
+ }
@@ -1,9 +1,8 @@
1
1
  {
2
2
  "name": "claude-live",
3
- "version": "0.1.0",
3
+ "version": "0.4.0",
4
4
  "description": "Realtime solar system visualizer for Claude Code sessions",
5
5
  "author": { "name": "marisancans" },
6
6
  "repository": "https://github.com/marisancans/claude-live",
7
- "keywords": ["visualizer", "activity", "realtime", "orbit"],
8
- "hooks": "./hooks/hooks.json"
7
+ "keywords": ["visualizer", "activity", "realtime", "orbit"]
9
8
  }
@@ -6,24 +6,21 @@ const portArgIdx = process.argv.findIndex(a => a === '--port' || a.startsWith('-
6
6
  const portArg = portArgIdx >= 0
7
7
  ? (process.argv[portArgIdx].includes('=') ? process.argv[portArgIdx].split('=')[1] : process.argv[portArgIdx + 1])
8
8
  : '43451'
9
- const desiredPort = parseInt(portArg, 10)
9
+ const port = parseInt(portArg, 10)
10
10
 
11
- let p = desiredPort
12
- const tryStart = async () => {
13
- try {
14
- const { port } = await createServer({ port: p })
15
- const url = `http://localhost:${port}`
16
- console.log(`claude-live running at ${url}`)
17
- if (p !== desiredPort) {
18
- console.log(`(port ${desiredPort} was in use)`)
19
- console.log(`Update your hook command to use port ${port}`)
20
- }
21
- console.log('\nAdd this to ~/.claude/settings.json hooks:')
22
- console.log(` curl -s -X POST ${url}/hook -H 'Content-Type: application/json' -d @- || true`)
23
- open(url)
24
- } catch (e) {
25
- if (e.code === 'EADDRINUSE') { p++; tryStart() }
26
- else { console.error(e); process.exit(1) }
11
+ try {
12
+ await createServer({ port })
13
+ const url = `http://localhost:${port}`
14
+ console.log(`claude-live running at ${url}`)
15
+ open(url)
16
+ } catch (e) {
17
+ if (e.code === 'EADDRINUSE') {
18
+ console.error(`Port ${port} is already in use.`)
19
+ console.error(`Either claude-live is already running, or another process is using port ${port}.`)
20
+ console.error(`Check: curl http://localhost:${port}/buffer`)
21
+ process.exit(1)
22
+ } else {
23
+ console.error(e)
24
+ process.exit(1)
27
25
  }
28
26
  }
29
- tryStart()
@@ -0,0 +1,34 @@
1
+ #!/bin/sh
2
+ # claude-live hook forwarder — reads URL from config with precedence:
3
+ # 1. CLAUDE_LIVE_URL env var (override)
4
+ # 2. .claude/claude-live.json (project)
5
+ # 3. ~/.config/claude-live/config.json (global)
6
+ # 4. http://localhost:43451 (default)
7
+
8
+ URL=""
9
+
10
+ # Debug: log that hook was called
11
+ echo "[claude-live-hook] hook called" >> /tmp/claude-live-hook.log 2>&1
12
+
13
+ # Project-level config
14
+ if [ -f ".claude/claude-live.json" ]; then
15
+ URL=$(cat .claude/claude-live.json 2>/dev/null | grep -o '"url" *: *"[^"]*"' | head -1 | sed 's/.*: *"//;s/"//')
16
+ fi
17
+
18
+ # Global config fallback
19
+ if [ -z "$URL" ] && [ -f "$HOME/.config/claude-live/config.json" ]; then
20
+ URL=$(cat "$HOME/.config/claude-live/config.json" 2>/dev/null | grep -o '"url" *: *"[^"]*"' | head -1 | sed 's/.*: *"//;s/"//')
21
+ fi
22
+
23
+ # Env var override
24
+ if [ -n "$CLAUDE_LIVE_URL" ]; then
25
+ URL="$CLAUDE_LIVE_URL"
26
+ fi
27
+
28
+ # Default
29
+ URL="${URL:-http://localhost:43451}"
30
+
31
+ # Debug: log what URL we're using and what we're sending
32
+ echo "[claude-live-hook] sending to $URL" >> /tmp/claude-live-hook.log 2>&1
33
+
34
+ curl -sf -X POST "$URL/hook" -H 'Content-Type: application/json' -d @- 2>/tmp/claude-live-hook-error.log || true
@@ -0,0 +1,33 @@
1
+ #!/bin/sh
2
+ # claude-live server launcher — reads URL from config with precedence:
3
+ # 1. CLAUDE_LIVE_URL env var (override)
4
+ # 2. .claude/claude-live.json (project)
5
+ # 3. ~/.config/claude-live/config.json (global)
6
+ # 4. http://localhost:43451 (default)
7
+
8
+ URL=""
9
+
10
+ # Project-level config
11
+ if [ -f ".claude/claude-live.json" ]; then
12
+ URL=$(cat .claude/claude-live.json 2>/dev/null | grep -o '"url" *: *"[^"]*"' | head -1 | sed 's/.*: *"//;s/"//')
13
+ fi
14
+
15
+ # Global config fallback
16
+ if [ -z "$URL" ] && [ -f "$HOME/.config/claude-live/config.json" ]; then
17
+ URL=$(cat "$HOME/.config/claude-live/config.json" 2>/dev/null | grep -o '"url" *: *"[^"]*"' | head -1 | sed 's/.*: *"//;s/"//')
18
+ fi
19
+
20
+ # Env var override
21
+ if [ -n "$CLAUDE_LIVE_URL" ]; then
22
+ URL="$CLAUDE_LIVE_URL"
23
+ fi
24
+
25
+ # Default
26
+ URL="${URL:-http://localhost:43451}"
27
+
28
+ # Only auto-start server if pointing to localhost
29
+ case "$URL" in
30
+ http://localhost:*|http://127.0.0.1:*)
31
+ curl -sf "$URL/buffer" >/dev/null 2>&1 || (npx claude-live@latest >/tmp/claude-live.log 2>&1 &)
32
+ ;;
33
+ esac