codevator 0.1.1 → 0.2.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.
package/README.md CHANGED
@@ -2,16 +2,10 @@
2
2
 
3
3
  Elevator music for your AI coding agent. Background sounds that play while Claude Code works and stop when it needs your attention.
4
4
 
5
- ## Install
5
+ ## Quick Start
6
6
 
7
7
  ```bash
8
- npm install -g codevator
9
- ```
10
-
11
- ## Setup
12
-
13
- ```bash
14
- codevator setup
8
+ npx codevator
15
9
  ```
16
10
 
17
11
  This installs hooks into Claude Code (`~/.claude/settings.json`) that automatically:
@@ -68,8 +62,7 @@ Setup also installs a Claude Code skill that lets the agent control music direct
68
62
  ## Uninstall
69
63
 
70
64
  ```bash
71
- codevator uninstall
72
- npm uninstall -g codevator
65
+ npx codevator uninstall
73
66
  ```
74
67
 
75
68
  ## License
package/dist/bin.js CHANGED
@@ -116,6 +116,7 @@ import fs3 from "fs";
116
116
  import path3 from "path";
117
117
  import os2 from "os";
118
118
  import { fileURLToPath as fileURLToPath2 } from "url";
119
+ import { execSync as execSync2 } from "child_process";
119
120
  var __dirname2 = path3.dirname(fileURLToPath2(import.meta.url));
120
121
  function getClaudeDir() {
121
122
  if (process.env.CODEVATOR_CLAUDE_HOME) return process.env.CODEVATOR_CLAUDE_HOME;
@@ -136,29 +137,45 @@ function writeSettings(settings) {
136
137
  fs3.mkdirSync(dir, { recursive: true });
137
138
  fs3.writeFileSync(getSettingsPath(), JSON.stringify(settings, null, 2));
138
139
  }
139
- var CODEVATOR_HOOKS = {
140
- PreToolUse: {
141
- matcher: "",
142
- hooks: [{ type: "command", command: "codevator play", async: true }]
143
- },
144
- Stop: {
145
- matcher: "",
146
- hooks: [{ type: "command", command: "codevator stop" }]
147
- },
148
- Notification: {
149
- matcher: "permission_prompt|idle_prompt",
150
- hooks: [{ type: "command", command: "codevator stop" }]
140
+ function codevatorCommand(sub, extra) {
141
+ const isGlobal = isGloballyInstalled();
142
+ const cmd = isGlobal ? `codevator ${sub}` : `npx -y codevator ${sub}`;
143
+ return { type: "command", command: cmd, ...extra };
144
+ }
145
+ function isGloballyInstalled() {
146
+ try {
147
+ execSync2("command -v codevator", { stdio: "ignore" });
148
+ return true;
149
+ } catch {
150
+ return false;
151
151
  }
152
- };
152
+ }
153
+ function buildHooks() {
154
+ return {
155
+ PreToolUse: {
156
+ matcher: "",
157
+ hooks: [codevatorCommand("play", { async: true })]
158
+ },
159
+ Stop: {
160
+ matcher: "",
161
+ hooks: [codevatorCommand("stop")]
162
+ },
163
+ Notification: {
164
+ matcher: "permission_prompt|idle_prompt",
165
+ hooks: [codevatorCommand("stop")]
166
+ }
167
+ };
168
+ }
153
169
  function isCodevatorHook(entry) {
154
170
  return entry?.hooks?.some(
155
- (h) => typeof h.command === "string" && h.command.startsWith("codevator")
171
+ (h) => typeof h.command === "string" && (h.command.startsWith("codevator") || h.command.includes("npx -y codevator"))
156
172
  );
157
173
  }
158
174
  function setupHooks() {
159
175
  const settings = readSettings();
160
176
  if (!settings.hooks) settings.hooks = {};
161
- for (const [event, hookEntry] of Object.entries(CODEVATOR_HOOKS)) {
177
+ const hooks = buildHooks();
178
+ for (const [event, hookEntry] of Object.entries(hooks)) {
162
179
  if (!settings.hooks[event]) settings.hooks[event] = [];
163
180
  settings.hooks[event] = settings.hooks[event].filter(
164
181
  (e) => !isCodevatorHook(e)
@@ -188,7 +205,7 @@ function removeSkill() {
188
205
  function removeHooks() {
189
206
  const settings = readSettings();
190
207
  if (!settings.hooks) return;
191
- for (const event of Object.keys(CODEVATOR_HOOKS)) {
208
+ for (const event of ["PreToolUse", "Stop", "Notification"]) {
192
209
  if (!settings.hooks[event]) continue;
193
210
  settings.hooks[event] = settings.hooks[event].filter(
194
211
  (e) => !isCodevatorHook(e)
@@ -219,7 +236,10 @@ var VALID_COMMANDS = [
219
236
  ];
220
237
  function parseArgs(argv) {
221
238
  const [cmd, ...args2] = argv;
222
- if (!cmd || !VALID_COMMANDS.includes(cmd)) {
239
+ if (!cmd) {
240
+ return { command: "setup", args: [] };
241
+ }
242
+ if (!VALID_COMMANDS.includes(cmd)) {
223
243
  return { command: "help", args: [] };
224
244
  }
225
245
  return { command: cmd, args: args2 };
@@ -314,16 +334,18 @@ function runUninstall() {
314
334
  function runHelp() {
315
335
  console.log(`\u{1F6D7} Codevator \u2014 Elevator music for your AI coding agent
316
336
 
317
- Usage: codevator <command>
337
+ Usage: npx codevator <command>
318
338
 
319
339
  Commands:
320
- setup Install hooks into Claude Code
340
+ setup Install hooks into Claude Code (default)
321
341
  mode <name> Set sound mode (elevator|typewriter|ambient|retro|minimal)
322
342
  on Enable sounds
323
343
  off Disable sounds
324
344
  volume <0-100> Set volume level
325
345
  status Show current settings
326
- uninstall Remove hooks from Claude Code`);
346
+ uninstall Remove hooks from Claude Code
347
+
348
+ Quick start: npx codevator`);
327
349
  }
328
350
 
329
351
  // src/bin.ts
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "codevator",
3
- "version": "0.1.1",
3
+ "version": "0.2.0",
4
4
  "type": "module",
5
5
  "description": "Elevator music for your AI coding agent",
6
6
  "bin": {
Binary file
package/sounds/retro.mp3 CHANGED
Binary file