vibeaudio 0.22.0 → 0.24.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 +7 -5
- package/package.json +1 -1
- package/src/cli.js +4 -1
- package/src/hooks.js +20 -0
package/README.md
CHANGED
|
@@ -442,17 +442,19 @@ Then `/reload-plugins` or a new session; `/plugin` shows `1 mod active`.
|
|
|
442
442
|
/vibeaudio genre jazz also: volume <n>, music on|off, speak off|auto|always, notify on|off, stop
|
|
443
443
|
/vibeaudio genre zen here genre, volume and music also take "here": save for this project only
|
|
444
444
|
/vibeaudio card make your week card; the pane shows it in terminals that draw images
|
|
445
|
-
/vibeaudio strip on an always-visible
|
|
445
|
+
/vibeaudio strip on an always-visible logo band above the prompt (off by default; strip off removes it)
|
|
446
|
+
/vibeaudio usage on add context fill and plan limits (ctx 42% 5h 31%) to the band (off by default; usage off removes it)
|
|
446
447
|
/vibeaudio doctor the setup check in a pane, each problem with its fix (vibe --doctor)
|
|
448
|
+
/vibeaudio help every command on one line, and the "here" option
|
|
447
449
|
```
|
|
448
450
|
|
|
449
|
-
While you are muted, a line above the prompt says how many minutes are left, so a forgotten mute does not look like a broken tool. Nothing else is shown unless you turn the strip on.
|
|
451
|
+
The pane is four cards under a logo header with a status pill (Playing, Ready, Muted or Music off): Now playing, Sound, Alerts and Share, which holds your last 7 days as a small chart and the week card buttons. Its colours come from the site and adapt to your Claude Code theme, light or dark. While you are muted, a line above the prompt says how many minutes are left, so a forgotten mute does not look like a broken tool. Nothing else is shown unless you turn the strip on.
|
|
450
452
|
|
|
451
|
-
The optional **strip** (`/vibeaudio strip on`, remembered across sessions)
|
|
453
|
+
The optional **strip** (`/vibeaudio strip on`, remembered across sessions) puts the VibeAudio logo above the prompt, three level bars that move while music is playing (an SVG on the Desktop app, text bars in the terminal). Next to it: the genre and volume, your last 7 days as the week card counts them (turns and time waited, read from `~/.vibeaudio/history.jsonl`), and what your other agents are doing (`api waiting, web working`, in yellow when one needs you). The buttons are **Mute**/**Unmute**, **Music**, **Genre >** (the next genre), **Vol -**, **Vol +**, **Week card** (makes the share card, then **Open card**) and **Controls**. In a short window it shrinks to one line. It runs `vibe --state` every 5 seconds and redraws the text bars twice a second only in the terminal, while it is on and music is playing; on the Desktop app the SVG animates itself, so only the level bars inside the headphones move. Tab to it with Ctrl+X then Tab. With `/vibeaudio usage on` it also shows how full the context window is and, on a Claude plan, your 5-hour and 7-day limits, turning the warning colour at 80%; it reads the same figures Claude Code's status line has, and nothing else. While Claude works, the spinner also says what is playing (`· ♪ jazz…`, or `· ♪ muted`).
|
|
452
454
|
|
|
453
455
|
- **Per project.** The pane's **Saving** button switches genre, volume and music between everywhere and this project, and the pane notes when this folder has its own settings (`vibe --genre zen --here`, found from a subfolder the way the CLI does). There is no way to remove a project's settings yet, in the mod or the CLI.
|
|
454
456
|
- **It changes nothing itself.** Every action runs the `vibe` command with a fixed argument list (no shell), so settings stay in `~/.vibeaudio/config.json` and the pane cannot disagree with the CLI. The one thing it keeps for itself is whether the strip is on, in Claude Code's own store for the mod. It needs `vibe` on your `PATH` (`npm i -g vibeaudio`) and **Claude Code 2.1.287 or later** (Desktop app 2.1.286). It draws in the terminal and the Desktop app; in the VS Code panel and `claude -p` the same commands answer in text. It makes no network request.
|
|
455
|
-
- **A mod is code, not configuration.** It runs inside Claude Code with your permissions and is not sandboxed, which is why `--install-hooks` never installs it for you. Read it first: it is [`mods/vibe/hooks/register.js`](mods/vibe/hooks/register.js), and `claude plugin validate mods/vibe` lists every call it makes (it reads
|
|
457
|
+
- **A mod is code, not configuration.** It runs inside Claude Code with your permissions and is not sandboxed, which is why `--install-hooks` never installs it for you; it prints the two commands until Claude Code lists the mod as installed. Read it first: it is [`mods/vibe/hooks/register.js`](mods/vibe/hooks/register.js), and `claude plugin validate mods/vibe` lists every call it makes (it reads three files in `~/.vibeaudio/` (`config.json`, `muted`, `history.jsonl`), your Claude Code theme, the session's usage figures (only with `usage on`), runs `vibe`, and draws).
|
|
456
458
|
- **`/vibe` stays.** It works on every Claude Code version and surface; the mod is the faster path where it loads. Remove the mod with `claude plugin uninstall vibeaudio-mod@vibeaudio`.
|
|
457
459
|
|
|
458
460
|
### Changing the sound later
|
|
@@ -874,7 +876,7 @@ The full order, highest first: **a flag** → **an environment variable** → **
|
|
|
874
876
|
| `--announce <text>` | Play the chime for something that isn't an agent (CI, a deploy, a script), then exit. Add `--outcome success\|failure\|attention` or `--exit-code $?` | `success` |
|
|
875
877
|
| `--stop` | Stop the background player, then exit | — |
|
|
876
878
|
| `--mute [minutes]` | Silence everything for a call, then exit | `60` min (`0` = until unmuted) |
|
|
877
|
-
| `--unmute` | Resume normal playback, then exit | — |
|
|
879
|
+
| `--unmute` | Resume normal playback, then exit; a turn still running gets its music back at once | — |
|
|
878
880
|
| `--clear-cache` | Delete all cached audio, then exit | — |
|
|
879
881
|
| `--mcp` | Run as an MCP stdio server for desktop apps | — |
|
|
880
882
|
| `--install-hooks` | Wire music into your agent's hooks (no wrapper needed) | — |
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "vibeaudio",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.24.0",
|
|
4
4
|
"description": "Procedural focus music while your AI coding tools (Claude Code, Codex, Cursor, Grok, Gemini, Copilot) think — a different arrangement per project.",
|
|
5
5
|
"bin": {
|
|
6
6
|
"vibeaudio": "bin/vibeaudio.js",
|
package/src/cli.js
CHANGED
|
@@ -777,6 +777,7 @@ function installHookTargets(ids, genre, volume, reactive, dryRun = false, typed
|
|
|
777
777
|
const slash = hooks.installSlashCommand({ dryRun });
|
|
778
778
|
if (!slash.installed) console.log(` \x1b[33m/vibe not installed: ${slash.reason} (${slash.file})\x1b[0m`);
|
|
779
779
|
else console.log(` ${"/vibe".padEnd(19)}→ ${dryRun ? "would write" : "control the music from inside Claude Code"} (${slash.file})`);
|
|
780
|
+
if (!dryRun && !hooks.modInstalled()) console.log(` \x1b[2mOptional: /plugin marketplace add kiril6/vibeaudio, then /plugin install vibeaudio-mod@vibeaudio - instant /vibeaudio controls, a pane and a band above the prompt.\x1b[0m`);
|
|
780
781
|
}
|
|
781
782
|
// Codex will not run a hook it has not been told to trust, so saying
|
|
782
783
|
// "done" without this would be reporting an install that isn't live yet.
|
|
@@ -1903,7 +1904,9 @@ async function run() {
|
|
|
1903
1904
|
|
|
1904
1905
|
if (!muteChange) {
|
|
1905
1906
|
setMuted(false);
|
|
1906
|
-
|
|
1907
|
+
// A turn already running gets its music back now; only an idle machine waits for a prompt.
|
|
1908
|
+
const resumed = require("./hooks").resumeAfterUnmute(genre, volume, { music, follow: typed.volume === undefined });
|
|
1909
|
+
console.log(`\x1b[32m🔊 Unmuted.\x1b[0m ${resumed ? "Music is back." : "Music returns on your next prompt."}\n`);
|
|
1907
1910
|
return;
|
|
1908
1911
|
}
|
|
1909
1912
|
|
package/src/hooks.js
CHANGED
|
@@ -1387,6 +1387,19 @@ function hookResume(raw, genre, volume, { reactive = false, follow = false, musi
|
|
|
1387
1387
|
return true;
|
|
1388
1388
|
}
|
|
1389
1389
|
|
|
1390
|
+
/**
|
|
1391
|
+
* An unmute while a turn is in flight: a mute stopped the player, and nothing
|
|
1392
|
+
* else would start one until the next prompt. Only for a session that is
|
|
1393
|
+
* working (a waiting one is waiting on the user, and says so with silence), and
|
|
1394
|
+
* never over a daemon already playing. Not reactive: that flag lives in the hook
|
|
1395
|
+
* commands, so a reactive install is plain until its next tool-driven resume.
|
|
1396
|
+
*/
|
|
1397
|
+
function resumeAfterUnmute(genre, volume, { music = true, follow = false } = {}) {
|
|
1398
|
+
if (!music || daemonRunning() || working(listSessions()).length === 0) return false;
|
|
1399
|
+
spawnDaemon(genre, volume, false, follow);
|
|
1400
|
+
return true;
|
|
1401
|
+
}
|
|
1402
|
+
|
|
1390
1403
|
/**
|
|
1391
1404
|
* The agent's session is over (quit, /clear, logout). A turn cut off by it
|
|
1392
1405
|
* never reaches Stop. Silent: nothing finished.
|
|
@@ -1641,6 +1654,11 @@ function slashCommandFile() {
|
|
|
1641
1654
|
return path.join(claudeConfigDir(), "commands", "vibe.md");
|
|
1642
1655
|
}
|
|
1643
1656
|
|
|
1657
|
+
// The optional in-app mod (mods/vibe). Claude Code records installed plugins by name in this file.
|
|
1658
|
+
function modInstalled(file = path.join(claudeConfigDir(), "plugins", "installed_plugins.json")) {
|
|
1659
|
+
try { return fs.readFileSync(file, "utf8").includes("vibeaudio-mod"); } catch { return false; }
|
|
1660
|
+
}
|
|
1661
|
+
|
|
1644
1662
|
function slashCommandText() {
|
|
1645
1663
|
const cli = `${shellQuote(process.execPath)} ${shellQuote(CLI_ENTRY)}`;
|
|
1646
1664
|
return `---
|
|
@@ -1720,6 +1738,7 @@ function uninstallHooks(file = null, { id = "claude" } = {}) {
|
|
|
1720
1738
|
module.exports = {
|
|
1721
1739
|
shellQuote,
|
|
1722
1740
|
claudeConfigDir,
|
|
1741
|
+
modInstalled,
|
|
1723
1742
|
codexHome,
|
|
1724
1743
|
geminiDir,
|
|
1725
1744
|
qwenHome,
|
|
@@ -1742,6 +1761,7 @@ module.exports = {
|
|
|
1742
1761
|
hookTool,
|
|
1743
1762
|
hookWait,
|
|
1744
1763
|
hookResume,
|
|
1764
|
+
resumeAfterUnmute,
|
|
1745
1765
|
isStuck,
|
|
1746
1766
|
STUCK_WINDOW,
|
|
1747
1767
|
agentState,
|