pingthings 0.1.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 (177) hide show
  1. package/LICENSE +11 -0
  2. package/README.md +262 -0
  3. package/bin/pingthings.js +78 -0
  4. package/package.json +34 -0
  5. package/packs/0ad-civilizations/manifest.json +77 -0
  6. package/packs/0ad-civilizations/sounds/alarm-alert.wav +0 -0
  7. package/packs/0ad-civilizations/sounds/alarm-attack.wav +0 -0
  8. package/packs/0ad-civilizations/sounds/alarm-defeat.wav +0 -0
  9. package/packs/0ad-civilizations/sounds/alarm-no-resource.wav +0 -0
  10. package/packs/0ad-civilizations/sounds/alarm-objective.wav +0 -0
  11. package/packs/0ad-civilizations/sounds/alarm-research-complete.wav +0 -0
  12. package/packs/0ad-civilizations/sounds/alarm-victory.wav +0 -0
  13. package/packs/0ad-civilizations/sounds/greek-as-you-wish.wav +0 -0
  14. package/packs/0ad-civilizations/sounds/greek-attack-1.wav +0 -0
  15. package/packs/0ad-civilizations/sounds/greek-build-1.wav +0 -0
  16. package/packs/0ad-civilizations/sounds/greek-heal-1.wav +0 -0
  17. package/packs/0ad-civilizations/sounds/greek-march-1.wav +0 -0
  18. package/packs/0ad-civilizations/sounds/greek-my-lord-1.wav +0 -0
  19. package/packs/0ad-civilizations/sounds/greek-my-lord-2.wav +0 -0
  20. package/packs/0ad-civilizations/sounds/greek-retreat-1.wav +0 -0
  21. package/packs/0ad-civilizations/sounds/greek-what-is-it-1.wav +0 -0
  22. package/packs/0ad-civilizations/sounds/greek-yes.wav +0 -0
  23. package/packs/0ad-civilizations/sounds/latin-attack-1.wav +0 -0
  24. package/packs/0ad-civilizations/sounds/latin-build-1.wav +0 -0
  25. package/packs/0ad-civilizations/sounds/latin-fight-1.wav +0 -0
  26. package/packs/0ad-civilizations/sounds/latin-heal-1.wav +0 -0
  27. package/packs/0ad-civilizations/sounds/latin-hello-1.wav +0 -0
  28. package/packs/0ad-civilizations/sounds/latin-my-lord-1.wav +0 -0
  29. package/packs/0ad-civilizations/sounds/latin-what-is-it.wav +0 -0
  30. package/packs/0ad-civilizations/sounds/persian-attack-1.wav +0 -0
  31. package/packs/0ad-civilizations/sounds/persian-by-your-order.wav +0 -0
  32. package/packs/0ad-civilizations/sounds/persian-forward-1.wav +0 -0
  33. package/packs/0ad-civilizations/sounds/persian-i-will-go.wav +0 -0
  34. package/packs/7kaa-soldiers/manifest.json +111 -0
  35. package/packs/7kaa-soldiers/sounds/00001-CH_A2.wav +0 -0
  36. package/packs/7kaa-soldiers/sounds/00006-NO_V2.wav +0 -0
  37. package/packs/7kaa-soldiers/sounds/00007-NO_V3.wav +0 -0
  38. package/packs/7kaa-soldiers/sounds/00008-MA_V1.wav +0 -0
  39. package/packs/7kaa-soldiers/sounds/00009-GR_V2.wav +0 -0
  40. package/packs/7kaa-soldiers/sounds/00010-GR_V3.wav +0 -0
  41. package/packs/7kaa-soldiers/sounds/00011-VI_V1.wav +0 -0
  42. package/packs/7kaa-soldiers/sounds/00012-NO_A1.wav +0 -0
  43. package/packs/7kaa-soldiers/sounds/00012-VI_V2.wav +0 -0
  44. package/packs/7kaa-soldiers/sounds/00013-GR_V1.wav +0 -0
  45. package/packs/7kaa-soldiers/sounds/00013-NO_A2.wav +0 -0
  46. package/packs/7kaa-soldiers/sounds/00014-MA_A1.wav +0 -0
  47. package/packs/7kaa-soldiers/sounds/00014-PE_V1.wav +0 -0
  48. package/packs/7kaa-soldiers/sounds/00015-GR_A1.wav +0 -0
  49. package/packs/7kaa-soldiers/sounds/00015-MA_V2.wav +0 -0
  50. package/packs/7kaa-soldiers/sounds/00016-MA_V3.wav +0 -0
  51. package/packs/7kaa-soldiers/sounds/00016-VI_A1.wav +0 -0
  52. package/packs/7kaa-soldiers/sounds/00017-MA_V4.wav +0 -0
  53. package/packs/7kaa-soldiers/sounds/00017-VI_A2.wav +0 -0
  54. package/packs/7kaa-soldiers/sounds/00018-PE_A2.wav +0 -0
  55. package/packs/7kaa-soldiers/sounds/00018-PE_V2.wav +0 -0
  56. package/packs/7kaa-soldiers/sounds/00019-PE_V3.wav +0 -0
  57. package/packs/7kaa-soldiers/sounds/00020-PE_A1.wav +0 -0
  58. package/packs/7kaa-soldiers/sounds/00020-PE_V4.wav +0 -0
  59. package/packs/7kaa-soldiers/sounds/00021-CH_A1.wav +0 -0
  60. package/packs/7kaa-soldiers/sounds/00021-CH_V1.wav +0 -0
  61. package/packs/7kaa-soldiers/sounds/00022-CH_V2.wav +0 -0
  62. package/packs/7kaa-soldiers/sounds/00022-JA_A1.wav +0 -0
  63. package/packs/7kaa-soldiers/sounds/00023-CH_V3.wav +0 -0
  64. package/packs/7kaa-soldiers/sounds/00023-JA_A2.wav +0 -0
  65. package/packs/7kaa-soldiers/sounds/00024-CH_V4.wav +0 -0
  66. package/packs/7kaa-soldiers/sounds/00025-CH_V5.wav +0 -0
  67. package/packs/7kaa-soldiers/sounds/00026-JA_V1.wav +0 -0
  68. package/packs/7kaa-soldiers/sounds/00027-JA_V2.wav +0 -0
  69. package/packs/7kaa-soldiers/sounds/00028-JA_V3.wav +0 -0
  70. package/packs/7kaa-soldiers/sounds/00029-JA_V4.wav +0 -0
  71. package/packs/7kaa-soldiers/sounds/00030-JA_V5.wav +0 -0
  72. package/packs/7kaa-soldiers/sounds/00035-MA_V5.wav +0 -0
  73. package/packs/7kaa-soldiers/sounds/00083-READY.wav +0 -0
  74. package/packs/7kaa-soldiers/sounds/00084-NO_V1.wav +0 -0
  75. package/packs/7kaa-soldiers/sounds/00085-EG_V1.wav +0 -0
  76. package/packs/7kaa-soldiers/sounds/00086-EG_V2.wav +0 -0
  77. package/packs/7kaa-soldiers/sounds/00087-EG_V3.wav +0 -0
  78. package/packs/7kaa-soldiers/sounds/00088-EG_V4.wav +0 -0
  79. package/packs/7kaa-soldiers/sounds/00089-IN_V1.wav +0 -0
  80. package/packs/7kaa-soldiers/sounds/00090-IN_V2.wav +0 -0
  81. package/packs/7kaa-soldiers/sounds/00091-IN_V3.wav +0 -0
  82. package/packs/7kaa-soldiers/sounds/00092-IN_V4.wav +0 -0
  83. package/packs/7kaa-soldiers/sounds/00093-ZU_V2.wav +0 -0
  84. package/packs/7kaa-soldiers/sounds/00094-ZU_V3.wav +0 -0
  85. package/packs/7kaa-soldiers/sounds/00095-ZU_V5.wav +0 -0
  86. package/packs/7kaa-soldiers/sounds/00096-ZU_V7.wav +0 -0
  87. package/packs/7kaa-soldiers/sounds/00097-ZU_V8.wav +0 -0
  88. package/packs/freedoom-arsenal/manifest.json +57 -0
  89. package/packs/freedoom-arsenal/sounds/dsbarexp.wav +0 -0
  90. package/packs/freedoom-arsenal/sounds/dsbfg.wav +0 -0
  91. package/packs/freedoom-arsenal/sounds/dsdoropn.wav +0 -0
  92. package/packs/freedoom-arsenal/sounds/dsdshtgn.wav +0 -0
  93. package/packs/freedoom-arsenal/sounds/dsgetpow.wav +0 -0
  94. package/packs/freedoom-arsenal/sounds/dsitemup.wav +0 -0
  95. package/packs/freedoom-arsenal/sounds/dsoof.wav +0 -0
  96. package/packs/freedoom-arsenal/sounds/dspistol.wav +0 -0
  97. package/packs/freedoom-arsenal/sounds/dsplasma.wav +0 -0
  98. package/packs/freedoom-arsenal/sounds/dspldeth.wav +0 -0
  99. package/packs/freedoom-arsenal/sounds/dspunch.wav +0 -0
  100. package/packs/freedoom-arsenal/sounds/dsrlaunc.wav +0 -0
  101. package/packs/freedoom-arsenal/sounds/dsrxplod.wav +0 -0
  102. package/packs/freedoom-arsenal/sounds/dssawup.wav +0 -0
  103. package/packs/freedoom-arsenal/sounds/dssgcock.wav +0 -0
  104. package/packs/freedoom-arsenal/sounds/dsshotgn.wav +0 -0
  105. package/packs/freedoom-arsenal/sounds/dsswtchn.wav +0 -0
  106. package/packs/freedoom-arsenal/sounds/dstelept.wav +0 -0
  107. package/packs/freedoom-arsenal/sounds/dswpnup.wav +0 -0
  108. package/packs/openarena-announcer/manifest.json +54 -0
  109. package/packs/openarena-announcer/sounds/accuracy.wav +0 -0
  110. package/packs/openarena-announcer/sounds/assist.wav +0 -0
  111. package/packs/openarena-announcer/sounds/defense.wav +0 -0
  112. package/packs/openarena-announcer/sounds/denied.wav +0 -0
  113. package/packs/openarena-announcer/sounds/excellent.wav +0 -0
  114. package/packs/openarena-announcer/sounds/fight.wav +0 -0
  115. package/packs/openarena-announcer/sounds/gauntlet.wav +0 -0
  116. package/packs/openarena-announcer/sounds/humiliation.wav +0 -0
  117. package/packs/openarena-announcer/sounds/impressive.wav +0 -0
  118. package/packs/openarena-announcer/sounds/one.wav +0 -0
  119. package/packs/openarena-announcer/sounds/perfect.wav +0 -0
  120. package/packs/openarena-announcer/sounds/prepare.wav +0 -0
  121. package/packs/openarena-announcer/sounds/sudden_death.wav +0 -0
  122. package/packs/openarena-announcer/sounds/takenlead.wav +0 -0
  123. package/packs/openarena-announcer/sounds/three.wav +0 -0
  124. package/packs/openarena-announcer/sounds/two.wav +0 -0
  125. package/packs/openarena-announcer/sounds/voc_holyshit.wav +0 -0
  126. package/packs/openarena-announcer/sounds/youwin.wav +0 -0
  127. package/packs/warzone2100-command/manifest.json +63 -0
  128. package/packs/warzone2100-command/sounds/construction-completed.wav +0 -0
  129. package/packs/warzone2100-command/sounds/design-completed.wav +0 -0
  130. package/packs/warzone2100-command/sounds/enemy-detected.wav +0 -0
  131. package/packs/warzone2100-command/sounds/incoming-enemy-transport.wav +0 -0
  132. package/packs/warzone2100-command/sounds/incoming-transmission.wav +0 -0
  133. package/packs/warzone2100-command/sounds/major-research-completed.wav +0 -0
  134. package/packs/warzone2100-command/sounds/mission-failed.wav +0 -0
  135. package/packs/warzone2100-command/sounds/mission-objective.wav +0 -0
  136. package/packs/warzone2100-command/sounds/mission-successful.wav +0 -0
  137. package/packs/warzone2100-command/sounds/mission-update.wav +0 -0
  138. package/packs/warzone2100-command/sounds/new-research-available.wav +0 -0
  139. package/packs/warzone2100-command/sounds/nexus-laugh1.wav +0 -0
  140. package/packs/warzone2100-command/sounds/nexus-laugh2.wav +0 -0
  141. package/packs/warzone2100-command/sounds/power-low.wav +0 -0
  142. package/packs/warzone2100-command/sounds/production-cancelled.wav +0 -0
  143. package/packs/warzone2100-command/sounds/production-completed.wav +0 -0
  144. package/packs/warzone2100-command/sounds/reinforcements-available.wav +0 -0
  145. package/packs/warzone2100-command/sounds/research-completed.wav +0 -0
  146. package/packs/warzone2100-command/sounds/retreat-heavy-damage.wav +0 -0
  147. package/packs/warzone2100-command/sounds/structure-under-attack.wav +0 -0
  148. package/packs/warzone2100-command/sounds/unit-repaired.wav +0 -0
  149. package/packs/wesnoth-combat/manifest.json +58 -0
  150. package/packs/wesnoth-combat/sounds/axe.wav +0 -0
  151. package/packs/wesnoth-combat/sounds/bow.wav +0 -0
  152. package/packs/wesnoth-combat/sounds/crossbow.wav +0 -0
  153. package/packs/wesnoth-combat/sounds/dwarf-laugh.wav +0 -0
  154. package/packs/wesnoth-combat/sounds/explosion.wav +0 -0
  155. package/packs/wesnoth-combat/sounds/fanfare-short.wav +0 -0
  156. package/packs/wesnoth-combat/sounds/flame-big.wav +0 -0
  157. package/packs/wesnoth-combat/sounds/gold.wav +0 -0
  158. package/packs/wesnoth-combat/sounds/gryphon-shriek-1.wav +0 -0
  159. package/packs/wesnoth-combat/sounds/hatchet.wav +0 -0
  160. package/packs/wesnoth-combat/sounds/heal.wav +0 -0
  161. package/packs/wesnoth-combat/sounds/lightning.wav +0 -0
  162. package/packs/wesnoth-combat/sounds/magic-dark.wav +0 -0
  163. package/packs/wesnoth-combat/sounds/magic-holy-1.wav +0 -0
  164. package/packs/wesnoth-combat/sounds/magic-missile-1.wav +0 -0
  165. package/packs/wesnoth-combat/sounds/open-chest.wav +0 -0
  166. package/packs/wesnoth-combat/sounds/potion.wav +0 -0
  167. package/packs/wesnoth-combat/sounds/sword-1.wav +0 -0
  168. package/packs/wesnoth-combat/sounds/wolf-growl-1.wav +0 -0
  169. package/src/cli/config.js +42 -0
  170. package/src/cli/install.js +8 -0
  171. package/src/cli/list.js +25 -0
  172. package/src/cli/play.js +127 -0
  173. package/src/cli/preview.js +30 -0
  174. package/src/cli/use.js +25 -0
  175. package/src/config.js +48 -0
  176. package/src/packs.js +130 -0
  177. package/src/player.js +39 -0
package/LICENSE ADDED
@@ -0,0 +1,11 @@
1
+ GNU GENERAL PUBLIC LICENSE
2
+ Version 2, June 1991
3
+
4
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
5
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
6
+ Everyone is permitted to copy and distribute verbatim copies
7
+ of this license document, but changing it is not allowed.
8
+
9
+ Audio assets are from Seven Kingdoms: Ancient Adversaries
10
+ Copyright 1997,1998 Enlight Software Ltd.
11
+ Licensed under GPL v2.
package/README.md ADDED
@@ -0,0 +1,262 @@
1
+ # pingthings
2
+
3
+ Notification sounds for Claude Code and other CLI tools. Like text tones for your terminal.
4
+
5
+ Pick a sound pack, and pingthings plays a random sound whenever Claude Code needs your attention. Or use **informational mode** to hear different sounds for different events — know if a task is done, if something went wrong, or if Claude needs your input, all by ear.
6
+
7
+ ## Install
8
+
9
+ ```bash
10
+ npm install -g pingthings
11
+ ```
12
+
13
+ ## Quick start
14
+
15
+ ```bash
16
+ # Play a random sound from the active pack
17
+ pingthings play
18
+
19
+ # See available packs
20
+ pingthings list
21
+
22
+ # Switch packs
23
+ pingthings use 7kaa-soldiers
24
+
25
+ # Preview a pack
26
+ pingthings preview 7kaa-soldiers
27
+
28
+ # Play a specific sound
29
+ pingthings play READY
30
+
31
+ # Play event-based sounds (informational mode)
32
+ pingthings play --event done
33
+ pingthings play --event error
34
+ pingthings play -e complete
35
+ ```
36
+
37
+ ## Claude Code setup
38
+
39
+ ### Basic (random sounds)
40
+
41
+ Add this to your `~/.claude/settings.json`:
42
+
43
+ ```json
44
+ {
45
+ "hooks": {
46
+ "Notification": [
47
+ {
48
+ "matcher": "",
49
+ "hooks": [
50
+ {
51
+ "type": "command",
52
+ "command": "pingthings play"
53
+ }
54
+ ]
55
+ }
56
+ ]
57
+ }
58
+ }
59
+ ```
60
+
61
+ ### Informational (event-based sounds)
62
+
63
+ For different sounds based on what Claude is doing, set up multiple hooks:
64
+
65
+ ```json
66
+ {
67
+ "hooks": {
68
+ "Notification": [
69
+ {
70
+ "matcher": "",
71
+ "hooks": [
72
+ {
73
+ "type": "command",
74
+ "command": "pingthings play --event permission"
75
+ }
76
+ ]
77
+ }
78
+ ],
79
+ "Stop": [
80
+ {
81
+ "matcher": "",
82
+ "hooks": [
83
+ {
84
+ "type": "command",
85
+ "command": "pingthings play --event complete"
86
+ }
87
+ ]
88
+ }
89
+ ],
90
+ "PostToolUseFailure": [
91
+ {
92
+ "matcher": "",
93
+ "hooks": [
94
+ {
95
+ "type": "command",
96
+ "command": "pingthings play --event error"
97
+ }
98
+ ]
99
+ }
100
+ ],
101
+ "StopFailure": [
102
+ {
103
+ "matcher": "",
104
+ "hooks": [
105
+ {
106
+ "type": "command",
107
+ "command": "pingthings play --event blocked"
108
+ }
109
+ ]
110
+ }
111
+ ]
112
+ }
113
+ }
114
+ ```
115
+
116
+ | Claude Code Event | Sound Event | When it fires |
117
+ |---|---|---|
118
+ | `Notification` | `permission` | Claude needs your input or approval |
119
+ | `Stop` | `complete` | Claude finishes a response |
120
+ | `PostToolUseFailure` | `error` | A tool fails (bash error, etc.) |
121
+ | `StopFailure` | `blocked` | API error, rate limit, auth issue |
122
+
123
+ ## Commands
124
+
125
+ | Command | Description |
126
+ |---------|-------------|
127
+ | `pingthings play [sound] [--event type]` | Play a sound (random, specific, or event-based) |
128
+ | `pingthings list` | Show available sound packs |
129
+ | `pingthings use <pack>` | Set the active sound pack |
130
+ | `pingthings preview <pack>` | Preview a random sound from a pack |
131
+ | `pingthings config [key] [val]` | Show or update configuration |
132
+ | `pingthings install <pack>` | Install a sound pack (coming soon) |
133
+
134
+ ## Configuration
135
+
136
+ Config lives at `~/.config/pingthings/config.json`:
137
+
138
+ ```json
139
+ {
140
+ "activePack": "7kaa-soldiers",
141
+ "mode": "random",
142
+ "specificSound": null
143
+ }
144
+ ```
145
+
146
+ - **activePack** — which sound pack to use
147
+ - **mode** — `"random"` (default), `"specific"`, or `"informational"`
148
+ - **specificSound** — sound name to always play when mode is `"specific"`
149
+
150
+ Set values via CLI:
151
+
152
+ ```bash
153
+ pingthings config mode random # any random sound
154
+ pingthings config mode specific # always the same sound
155
+ pingthings config mode informational # event-based sounds
156
+ pingthings config specificSound READY # set the sound for specific mode
157
+ ```
158
+
159
+ ## Modes
160
+
161
+ ### Random (default)
162
+ Plays any random sound from the active pack. Great for variety.
163
+
164
+ ### Specific
165
+ Always plays the same configured sound. Set it with `pingthings config specificSound <name>`.
166
+
167
+ ### Informational
168
+ Plays different sounds based on what's happening. Use the `--event` flag to tell pingthings what type of event occurred:
169
+
170
+ | Event | Meaning | Example trigger |
171
+ |-------|---------|----------------|
172
+ | `done` | Task/step finished | Claude completed a request |
173
+ | `permission` | Needs approval | Claude needs tool permission |
174
+ | `complete` | Major milestone done | Project or phase finished |
175
+ | `error` | Something went wrong | Build failed, test failed |
176
+ | `blocked` | User action needed | Need to update a dashboard, grant access |
177
+
178
+ ```bash
179
+ pingthings play --event done # "task finished" sound
180
+ pingthings play --event error # "something broke" sound
181
+ pingthings play -e permission # "need your approval" sound
182
+ ```
183
+
184
+ Each pack maps its sounds to events thematically:
185
+ - **7kaa-soldiers**: voice acknowledgements for done, "READY" for permission, attack grunts for errors
186
+ - **openarena-announcer**: "excellent!" for done, "prepare!" for permission, "denied!" for errors
187
+ - **wesnoth-combat**: gold collect for done, chest open for permission, explosions for errors
188
+ - **freedoom-arsenal**: item pickup for done, shotgun cock for permission, barrel explosion for errors
189
+ - **warzone2100-command**: "research completed" for done, "incoming transmission" for permission, "mission failed" for errors
190
+ - **0ad-civilizations**: Greek "as you wish" for done, "my lord?" for permission, alarm horns for errors
191
+
192
+ ## Built-in packs
193
+
194
+ ### 7kaa-soldiers
195
+ Soldier acknowledgement voice lines from **Seven Kingdoms: Ancient Adversaries** — 53 sounds from all 10 civilizations (Norman, Maya, Greek, Viking, Persian, Chinese, Japanese, Egyptian, Indian, Zulu). License: GPL v2.
196
+
197
+ ### wesnoth-combat
198
+ Fantasy combat and magic sounds from **Battle for Wesnoth** — 19 sounds including swords, bows, spells, explosions, gold collection, healing, and a dwarf laugh. License: GPL v2+.
199
+
200
+ ### openarena-announcer
201
+ Arena FPS announcer voice lines from **OpenArena** — 18 sounds including "excellent!", "impressive!", "fight!", "perfect!", "denied!", and more. License: GPL v2.
202
+
203
+ ### freedoom-arsenal
204
+ Retro FPS weapon and pickup sounds from **Freedoom** — 19 sounds including shotgun, plasma rifle, BFG, rocket launcher, item pickups, and teleport. License: BSD-3-Clause.
205
+
206
+ ### warzone2100-command
207
+ Sci-fi military commander voice lines from **Warzone 2100** — 21 sounds including "research completed", "mission successful", "incoming transmission", "enemy detected", and NEXUS AI laughs. License: GPL v2.
208
+
209
+ ### 0ad-civilizations
210
+ Ancient civilization voice lines and alerts from **0 A.D.** — 28 sounds with Greek, Latin, and Persian voice acknowledgements ("my lord", "as you wish", "by your order") plus alarm sounds (victory, defeat, attack). License: CC-BY-SA 3.0.
211
+
212
+ ## Custom packs
213
+
214
+ Place packs in `~/.config/pingthings/packs/<pack-name>/`:
215
+
216
+ ```
217
+ my-pack/
218
+ manifest.json
219
+ sounds/
220
+ sound1.wav
221
+ sound2.wav
222
+ ```
223
+
224
+ Minimal `manifest.json`:
225
+
226
+ ```json
227
+ {
228
+ "name": "my-pack",
229
+ "description": "My custom sound pack",
230
+ "license": "MIT",
231
+ "credits": "Your Name"
232
+ }
233
+ ```
234
+
235
+ The `sounds` field in the manifest is optional — if omitted, all `.wav`, `.mp3`, `.ogg`, and `.flac` files in the `sounds/` directory are used.
236
+
237
+ To support informational mode, add an `events` field mapping event types to sounds:
238
+
239
+ ```json
240
+ {
241
+ "name": "my-pack",
242
+ "description": "My custom sound pack",
243
+ "license": "MIT",
244
+ "credits": "Your Name",
245
+ "events": {
246
+ "done": ["sounds/success.wav", "sounds/complete.wav"],
247
+ "permission": ["sounds/question.wav"],
248
+ "complete": ["sounds/fanfare.wav"],
249
+ "error": ["sounds/alarm.wav", "sounds/buzz.wav"],
250
+ "blocked": ["sounds/warning.wav"]
251
+ }
252
+ }
253
+ ```
254
+
255
+ ## Requirements
256
+
257
+ - Node.js >= 18
258
+ - macOS (`afplay`) or Linux (`paplay` / `aplay`)
259
+
260
+ ## License
261
+
262
+ GPL v2 — includes audio from [Seven Kingdoms: Ancient Adversaries](https://github.com/the3dfxdude/7kaa) (GPL v2).
@@ -0,0 +1,78 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { readFileSync } from 'node:fs';
4
+ import { dirname, join } from 'node:path';
5
+ import { fileURLToPath } from 'node:url';
6
+
7
+ const __dirname = dirname(fileURLToPath(import.meta.url));
8
+ const pkg = JSON.parse(readFileSync(join(__dirname, '..', 'package.json'), 'utf8'));
9
+
10
+ const command = process.argv[2];
11
+ const args = process.argv.slice(3);
12
+
13
+ const commands = {
14
+ play: () => import('../src/cli/play.js'),
15
+ list: () => import('../src/cli/list.js'),
16
+ use: () => import('../src/cli/use.js'),
17
+ preview: () => import('../src/cli/preview.js'),
18
+ config: () => import('../src/cli/config.js'),
19
+ install: () => import('../src/cli/install.js'),
20
+ };
21
+
22
+ function showHelp() {
23
+ console.log(`
24
+ pingthings v${pkg.version} — ${pkg.description}
25
+
26
+ Usage: pingthings <command> [options]
27
+
28
+ Commands:
29
+ play [sound] Play a sound from the active pack (random by default)
30
+ list Show available sound packs
31
+ use <pack> Set the active sound pack
32
+ preview <pack> Preview a random sound from a pack
33
+ config [key] [val] Show or update configuration
34
+ install <pack> Install a sound pack (coming soon)
35
+
36
+ Options:
37
+ --help, -h Show this help message
38
+ --version, -v Show version number
39
+
40
+ Modes:
41
+ random Play any random sound (default)
42
+ specific Always play the same configured sound
43
+ informational Play sounds mapped to event types
44
+
45
+ Examples:
46
+ pingthings play Play a random sound
47
+ pingthings play 00083-READY Play a specific sound
48
+ pingthings play --event done Play a "task done" sound
49
+ pingthings play -e error Play an "error" sound
50
+ pingthings list List all available packs
51
+ pingthings use 7kaa-soldiers Switch to a pack
52
+ pingthings config mode informational Enable event-based sounds
53
+ `);
54
+ }
55
+
56
+ if (!command || command === '--help' || command === '-h') {
57
+ showHelp();
58
+ process.exit(0);
59
+ }
60
+
61
+ if (command === '--version' || command === '-v') {
62
+ console.log(pkg.version);
63
+ process.exit(0);
64
+ }
65
+
66
+ if (!commands[command]) {
67
+ console.error(`Unknown command: ${command}`);
68
+ console.error('Run "pingthings --help" for usage.');
69
+ process.exit(1);
70
+ }
71
+
72
+ try {
73
+ const mod = await commands[command]();
74
+ await mod.default(args);
75
+ } catch (err) {
76
+ console.error(`Error: ${err.message}`);
77
+ process.exit(1);
78
+ }
package/package.json ADDED
@@ -0,0 +1,34 @@
1
+ {
2
+ "name": "pingthings",
3
+ "version": "0.1.0",
4
+ "description": "Notification sounds for Claude Code and other CLI tools",
5
+ "type": "module",
6
+ "license": "GPL-2.0",
7
+ "bin": {
8
+ "pingthings": "./bin/pingthings.js"
9
+ },
10
+ "files": [
11
+ "bin/",
12
+ "src/",
13
+ "packs/"
14
+ ],
15
+ "engines": {
16
+ "node": ">=18"
17
+ },
18
+ "scripts": {
19
+ "test": "node --test test/*.test.js"
20
+ },
21
+ "keywords": [
22
+ "claude-code",
23
+ "notification",
24
+ "sound",
25
+ "cli",
26
+ "hook"
27
+ ],
28
+ "repository": {
29
+ "type": "git",
30
+ "url": "https://github.com/JustPinero/pingthings.git"
31
+ },
32
+ "homepage": "https://github.com/JustPinero/pingthings",
33
+ "author": "Justin Pinero"
34
+ }
@@ -0,0 +1,77 @@
1
+ {
2
+ "name": "0ad-civilizations",
3
+ "description": "Ancient civilization voice lines and alerts from 0 A.D.",
4
+ "version": "1.0.0",
5
+ "license": "CC-BY-SA-3.0",
6
+ "credits": "Wildfire Games / 0 A.D. (https://github.com/0ad/0ad) — audio licensed under CC-BY-SA 3.0",
7
+ "sounds": [
8
+ "sounds/alarm-alert.wav",
9
+ "sounds/alarm-attack.wav",
10
+ "sounds/alarm-defeat.wav",
11
+ "sounds/alarm-no-resource.wav",
12
+ "sounds/alarm-objective.wav",
13
+ "sounds/alarm-research-complete.wav",
14
+ "sounds/alarm-victory.wav",
15
+ "sounds/greek-as-you-wish.wav",
16
+ "sounds/greek-attack-1.wav",
17
+ "sounds/greek-build-1.wav",
18
+ "sounds/greek-heal-1.wav",
19
+ "sounds/greek-march-1.wav",
20
+ "sounds/greek-my-lord-1.wav",
21
+ "sounds/greek-my-lord-2.wav",
22
+ "sounds/greek-retreat-1.wav",
23
+ "sounds/greek-what-is-it-1.wav",
24
+ "sounds/greek-yes.wav",
25
+ "sounds/latin-attack-1.wav",
26
+ "sounds/latin-build-1.wav",
27
+ "sounds/latin-fight-1.wav",
28
+ "sounds/latin-heal-1.wav",
29
+ "sounds/latin-hello-1.wav",
30
+ "sounds/latin-my-lord-1.wav",
31
+ "sounds/latin-what-is-it.wav",
32
+ "sounds/persian-attack-1.wav",
33
+ "sounds/persian-by-your-order.wav",
34
+ "sounds/persian-forward-1.wav",
35
+ "sounds/persian-i-will-go.wav"
36
+ ],
37
+ "events": {
38
+ "done": [
39
+ "sounds/greek-as-you-wish.wav",
40
+ "sounds/greek-yes.wav",
41
+ "sounds/greek-build-1.wav",
42
+ "sounds/latin-build-1.wav",
43
+ "sounds/persian-by-your-order.wav",
44
+ "sounds/persian-i-will-go.wav",
45
+ "sounds/alarm-research-complete.wav"
46
+ ],
47
+ "permission": [
48
+ "sounds/greek-my-lord-1.wav",
49
+ "sounds/greek-my-lord-2.wav",
50
+ "sounds/greek-what-is-it-1.wav",
51
+ "sounds/latin-my-lord-1.wav",
52
+ "sounds/latin-what-is-it.wav",
53
+ "sounds/latin-hello-1.wav",
54
+ "sounds/alarm-objective.wav"
55
+ ],
56
+ "complete": [
57
+ "sounds/alarm-victory.wav",
58
+ "sounds/greek-march-1.wav",
59
+ "sounds/greek-heal-1.wav",
60
+ "sounds/latin-heal-1.wav",
61
+ "sounds/persian-forward-1.wav"
62
+ ],
63
+ "error": [
64
+ "sounds/alarm-attack.wav",
65
+ "sounds/alarm-defeat.wav",
66
+ "sounds/alarm-no-resource.wav",
67
+ "sounds/greek-attack-1.wav",
68
+ "sounds/latin-attack-1.wav",
69
+ "sounds/persian-attack-1.wav"
70
+ ],
71
+ "blocked": [
72
+ "sounds/alarm-alert.wav",
73
+ "sounds/greek-retreat-1.wav",
74
+ "sounds/latin-fight-1.wav"
75
+ ]
76
+ }
77
+ }
@@ -0,0 +1,111 @@
1
+ {
2
+ "name": "7kaa-soldiers",
3
+ "description": "Soldier acknowledgement voice lines from Seven Kingdoms: Ancient Adversaries",
4
+ "version": "1.0.0",
5
+ "license": "GPL-2.0",
6
+ "credits": "Enlight Software Ltd. / Seven Kingdoms: Ancient Adversaries (https://github.com/the3dfxdude/7kaa)",
7
+ "sounds": [
8
+ "sounds/00001-CH_A2.wav",
9
+ "sounds/00006-NO_V2.wav",
10
+ "sounds/00007-NO_V3.wav",
11
+ "sounds/00008-MA_V1.wav",
12
+ "sounds/00009-GR_V2.wav",
13
+ "sounds/00010-GR_V3.wav",
14
+ "sounds/00011-VI_V1.wav",
15
+ "sounds/00012-NO_A1.wav",
16
+ "sounds/00012-VI_V2.wav",
17
+ "sounds/00013-GR_V1.wav",
18
+ "sounds/00013-NO_A2.wav",
19
+ "sounds/00014-MA_A1.wav",
20
+ "sounds/00014-PE_V1.wav",
21
+ "sounds/00015-GR_A1.wav",
22
+ "sounds/00015-MA_V2.wav",
23
+ "sounds/00016-MA_V3.wav",
24
+ "sounds/00016-VI_A1.wav",
25
+ "sounds/00017-MA_V4.wav",
26
+ "sounds/00017-VI_A2.wav",
27
+ "sounds/00018-PE_A2.wav",
28
+ "sounds/00018-PE_V2.wav",
29
+ "sounds/00019-PE_V3.wav",
30
+ "sounds/00020-PE_A1.wav",
31
+ "sounds/00020-PE_V4.wav",
32
+ "sounds/00021-CH_A1.wav",
33
+ "sounds/00021-CH_V1.wav",
34
+ "sounds/00022-CH_V2.wav",
35
+ "sounds/00022-JA_A1.wav",
36
+ "sounds/00023-CH_V3.wav",
37
+ "sounds/00023-JA_A2.wav",
38
+ "sounds/00024-CH_V4.wav",
39
+ "sounds/00025-CH_V5.wav",
40
+ "sounds/00026-JA_V1.wav",
41
+ "sounds/00027-JA_V2.wav",
42
+ "sounds/00028-JA_V3.wav",
43
+ "sounds/00029-JA_V4.wav",
44
+ "sounds/00030-JA_V5.wav",
45
+ "sounds/00035-MA_V5.wav",
46
+ "sounds/00083-READY.wav",
47
+ "sounds/00084-NO_V1.wav",
48
+ "sounds/00085-EG_V1.wav",
49
+ "sounds/00086-EG_V2.wav",
50
+ "sounds/00087-EG_V3.wav",
51
+ "sounds/00088-EG_V4.wav",
52
+ "sounds/00089-IN_V1.wav",
53
+ "sounds/00090-IN_V2.wav",
54
+ "sounds/00091-IN_V3.wav",
55
+ "sounds/00092-IN_V4.wav",
56
+ "sounds/00093-ZU_V2.wav",
57
+ "sounds/00094-ZU_V3.wav",
58
+ "sounds/00095-ZU_V5.wav",
59
+ "sounds/00096-ZU_V7.wav",
60
+ "sounds/00097-ZU_V8.wav"
61
+ ],
62
+ "events": {
63
+ "done": [
64
+ "sounds/00006-NO_V2.wav",
65
+ "sounds/00008-MA_V1.wav",
66
+ "sounds/00009-GR_V2.wav",
67
+ "sounds/00011-VI_V1.wav",
68
+ "sounds/00014-PE_V1.wav",
69
+ "sounds/00021-CH_V1.wav",
70
+ "sounds/00026-JA_V1.wav",
71
+ "sounds/00084-NO_V1.wav",
72
+ "sounds/00085-EG_V1.wav",
73
+ "sounds/00089-IN_V1.wav",
74
+ "sounds/00093-ZU_V2.wav"
75
+ ],
76
+ "permission": [
77
+ "sounds/00083-READY.wav",
78
+ "sounds/00013-GR_V1.wav",
79
+ "sounds/00018-PE_V2.wav",
80
+ "sounds/00022-CH_V2.wav",
81
+ "sounds/00027-JA_V2.wav",
82
+ "sounds/00090-IN_V2.wav"
83
+ ],
84
+ "complete": [
85
+ "sounds/00007-NO_V3.wav",
86
+ "sounds/00010-GR_V3.wav",
87
+ "sounds/00016-MA_V3.wav",
88
+ "sounds/00019-PE_V3.wav",
89
+ "sounds/00023-CH_V3.wav",
90
+ "sounds/00028-JA_V3.wav",
91
+ "sounds/00087-EG_V3.wav",
92
+ "sounds/00091-IN_V3.wav"
93
+ ],
94
+ "error": [
95
+ "sounds/00001-CH_A2.wav",
96
+ "sounds/00012-NO_A1.wav",
97
+ "sounds/00013-NO_A2.wav",
98
+ "sounds/00014-MA_A1.wav",
99
+ "sounds/00015-GR_A1.wav",
100
+ "sounds/00016-VI_A1.wav",
101
+ "sounds/00018-PE_A2.wav",
102
+ "sounds/00021-CH_A1.wav",
103
+ "sounds/00022-JA_A1.wav"
104
+ ],
105
+ "blocked": [
106
+ "sounds/00017-VI_A2.wav",
107
+ "sounds/00020-PE_A1.wav",
108
+ "sounds/00023-JA_A2.wav"
109
+ ]
110
+ }
111
+ }