ai-notify 0.4.7 → 0.4.9

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.ja.md CHANGED
@@ -66,12 +66,17 @@ ai-notify uninstall # 配線をきれいに削除
66
66
  **ペインの設定を1コマンドで。** エージェントを動かす端末の中でこれを実行すると、読み上げ名・声・音量・**ターミナルのタブ名**を一度に設定できます。メニュー操作は不要:
67
67
 
68
68
  ```sh
69
- ai-notify use api Kyoko # 名前「api」+声 Kyoko+タブ名→api
70
- ai-notify use web Eddy 0.8 # +音量 0.8
71
- ai-notify use infra vv3 # VOICEVOX スピーカー3(例: ずんだもん)
72
- ai-notify use clear # このペインをリセット
69
+ ai-notify use api Kyoko # 名前「api」+声 Kyoko+タブ名→api
70
+ ai-notify use web Eddy 0.8 # +音量 0.8
71
+ ai-notify use zunda ずんだもん # 声は VOICEVOX キャラ名で指定(vv3 でも可)
72
+ ai-notify use エックスズンダモン ずんだもん --tab x_zunda # 読み上げ名とタブ名を別々に
73
+ ai-notify use clear # このペインをリセット
73
74
  ```
74
75
 
76
+ `声` は `say` の名前/番号(`Kyoko`・`3`)、VOICEVOX の**キャラ名**(`ずんだもん`)、`vv<id>`(`vv3`)が使えます。`--tab` で読み上げ名と別のタブ名を付けられます。
77
+
78
+ > タブ名の変更はベストエフォートで、標準のタイトルエスケープ(OSC 0+2)を送ります。**Terminal.app** と **iTerm2** は反映します。**JetBrains 系(WebStorm/IntelliJ)は新ターミナル(Reworked・2025.2 以降が既定)でのみ反映**し、バージョンによってはタブを再アクティブにすると名前が戻ります([IDEA-277846](https://youtrack.jetbrains.com/issue/IDEA-277846/Support-changing-terminal-tab-title-by-escape-sequences))。プロンプト毎にタイトルを書き換えるシェル設定でも上書きされます。読み上げ名と声は端末に関係なく常に有効です。
79
+
75
80
  ペイン別の上書き — エージェントを起動する**前**に、その端末で `export` する:
76
81
 
77
82
  ```sh
package/README.md CHANGED
@@ -67,12 +67,17 @@ ai-notify uninstall # cleanly remove wiring
67
67
  **Set up a pane in one command.** Run this *in* the terminal where the agent runs — it names the pane (spoken in the read-out), picks its voice, sets its volume, and renames the terminal tab, all at once. No menu hopping:
68
68
 
69
69
  ```sh
70
- ai-notify use api Kyoko # name "api" + voice Kyoko + tab → "api"
71
- ai-notify use web Eddy 0.8 # + volume 0.8
72
- ai-notify use infra vv3 # VOICEVOX speaker 3 (e.g. ずんだもん)
73
- ai-notify use clear # reset this pane
70
+ ai-notify use api Kyoko # name "api" + voice Kyoko + tab → "api"
71
+ ai-notify use web Eddy 0.8 # + volume 0.8
72
+ ai-notify use zunda ずんだもん # voice by VOICEVOX character name (or vv3)
73
+ ai-notify use エックスズンダモン ずんだもん --tab x_zunda # spoken name ≠ tab title
74
+ ai-notify use clear # reset this pane
74
75
  ```
75
76
 
77
+ `voice` is a `say` name/number (`Kyoko`, `3`), a VOICEVOX **character name** (`ずんだもん`), or `vv<id>` (`vv3`). `--tab` sets a different terminal tab title from the spoken name.
78
+
79
+ > Tab renaming is best-effort — it sends the standard title escape (OSC 0 + 2), which **Terminal.app** and **iTerm2** honor. **JetBrains IDEs** (WebStorm/IntelliJ) honor it only with the **Reworked terminal** (default in 2025.2+); some versions reset the name when you re-activate the tab ([IDEA-277846](https://youtrack.jetbrains.com/issue/IDEA-277846/Support-changing-terminal-tab-title-by-escape-sequences)). A shell that rewrites the title every prompt can also override it. The spoken name and voice always apply regardless.
80
+
76
81
  Per-window overrides — `export` these in a terminal *before* launching the agent:
77
82
 
78
83
  ```sh
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ai-notify",
3
- "version": "0.4.7",
3
+ "version": "0.4.9",
4
4
  "description": "Desktop, sound, and spoken notifications for terminal AI coding agents (Claude Code, Codex, Gemini, ...) — with one mute switch that covers all of them, across every terminal.",
5
5
  "type": "module",
6
6
  "bin": {
package/src/cli.mjs CHANGED
@@ -510,18 +510,31 @@ const cmds = {
510
510
  // and volume — and rename the terminal tab — in a single command, instead of
511
511
  // doing each from the menu bar. Keyed by this shell's tty (which the agent's
512
512
  // hook resolves to as well), so it just works for the agent running here.
513
- // use <name> [voice] [volume] | use clear
514
- // voice: a system voice name/number (e.g. Kyoko, 3) or VOICEVOX as vv<id> (vv3).
513
+ // use <name> [voice] [volume] [--tab <title>] | use clear
514
+ // voice: a system voice name/number (Kyoko, 3), a VOICEVOX character name
515
+ // (ずんだもん), or vv<id> (vv3). --tab: separate tab title (default <name>).
515
516
  use() {
516
- const [name, voiceArg, volArg] = positionals;
517
517
  const tty = controllingTty();
518
518
  if (!tty) {
519
519
  console.error('`ai-notify use` must run inside a terminal pane (no controlling tty found).');
520
520
  process.exit(1);
521
521
  }
522
+ // Pull --tab and its value out first, so the tab title (any token) is never
523
+ // mistaken for the voice or volume positional.
524
+ const rest = args.slice(1);
525
+ let tabTitle;
526
+ const pos = [];
527
+ for (let i = 0; i < rest.length; i++) {
528
+ if (rest[i] === '--tab') {
529
+ if (rest[i + 1] && !rest[i + 1].startsWith('--')) tabTitle = rest[++i];
530
+ continue;
531
+ }
532
+ if (!rest[i].startsWith('--')) pos.push(rest[i]);
533
+ }
534
+ const [name, voiceArg, volArg] = pos;
522
535
  if (!name || name === 'clear' || name === 'reset') {
523
536
  updatePaneSetting(tty, { speakName: null, tts: null, voice: null, speaker: null, volume: null });
524
- process.stdout.write('\u001b]0;\u0007'); // clear the tab title (best-effort)
537
+ process.stdout.write('\u001b]0;\u0007\u001b]2;\u0007'); // clear tab title via OSC 0 + 2 (best-effort)
525
538
  return log(`✓ pane reset (${tty})`);
526
539
  }
527
540
 
@@ -534,16 +547,28 @@ const cmds = {
534
547
  patch.speaker = Number(vv[1]);
535
548
  patch.voice = null;
536
549
  voiceLabel = `VOICEVOX ${vv[1]}`;
550
+ } else if (resolveVoice(voiceArg, curatedVoices(10))) {
551
+ patch.tts = 'say';
552
+ patch.voice = resolveVoice(voiceArg, curatedVoices(10));
553
+ patch.speaker = null;
554
+ voiceLabel = patch.voice;
537
555
  } else {
538
- const picked = resolveVoice(voiceArg, curatedVoices(10));
539
- if (!picked) {
540
- console.error(`unknown voice: ${voiceArg} (names/numbers: ai-notify voice; VOICEVOX: vv<id>)`);
556
+ // A VOICEVOX character by name (e.g. ずんだもん) — resolve via the engine.
557
+ const url = readConfig().voicevox?.url || voicevox.DEFAULT_URL;
558
+ const chars = voicevox.isAvailable(url) ? voicevox.listCharacters(url) : [];
559
+ const hit = chars.find((c) => c.name === voiceArg) || chars.find((c) => c.name.includes(voiceArg));
560
+ if (!hit) {
561
+ console.error(
562
+ `unknown voice: ${voiceArg}\n` +
563
+ ' say voice: a name/number from `ai-notify voice` (e.g. Kyoko, 3)\n' +
564
+ ' VOICEVOX: a character name (e.g. ずんだもん; engine must be running) or vv<id> (vv3)'
565
+ );
541
566
  process.exit(1);
542
567
  }
543
- patch.tts = 'say';
544
- patch.voice = picked;
545
- patch.speaker = null;
546
- voiceLabel = picked;
568
+ patch.tts = 'voicevox';
569
+ patch.speaker = hit.id;
570
+ patch.voice = null;
571
+ voiceLabel = `${hit.name} (VOICEVOX ${hit.id})`;
547
572
  }
548
573
  }
549
574
  if (volArg !== undefined) {
@@ -552,14 +577,16 @@ const cmds = {
552
577
  }
553
578
 
554
579
  updatePaneSetting(tty, patch);
555
- // Rename this terminal tab/window to the pane name (best-effort — a shell
556
- // that rewrites the title on each prompt may override it after you return).
557
- process.stdout.write(`\u001b]0;${name}\u0007`);
580
+ // Rename this terminal tab/window (best-effort — a shell that rewrites the
581
+ // title on each prompt may override it after you return to the prompt).
582
+ const tab = tabTitle || name;
583
+ process.stdout.write(`\u001b]0;${tab}\u0007\u001b]2;${tab}\u0007`);
558
584
 
559
585
  const bits = [`name ${name}`];
560
586
  if (voiceLabel) bits.push(`voice ${voiceLabel}`);
561
587
  if (patch.volume !== undefined) bits.push(`volume ${patch.volume}`);
562
- log(`✓ ${bits.join(' · ')} · tab renamed`);
588
+ bits.push(`tab ${tab}`);
589
+ log(`✓ ${bits.join(' · ')}`);
563
590
  },
564
591
 
565
592
  // Get/set the VOICEVOX base prosody (the normal-tone scales the menu bar
@@ -766,7 +793,7 @@ function printHelp() {
766
793
  Usage:
767
794
  ai-notify init [--dry-run] [--only claude,codex] wire detected agents
768
795
  ai-notify uninstall [--only ...] remove wiring
769
- ai-notify use <name> [voice] [vol] name THIS pane + set its voice + rename the tab, at once
796
+ ai-notify use <name> [voice] [vol] [--tab <t>] name THIS pane + voice + tab, at once (voice: Kyoko | 3 | ずんだもん | vv3)
770
797
  ai-notify toggle | on | off | status control the mute switch
771
798
  ai-notify volume [0.0-2.0] get/set output volume
772
799
  ai-notify voice [number|name|preview|default] pick the spoken voice