ai-notify 0.4.6 → 0.4.8

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
@@ -51,6 +51,7 @@ ai-notify init # インストール済みのエージェントを自動
51
51
 
52
52
  ```sh
53
53
  ai-notify init [--dry-run] [--only claude,codex] # 検出したエージェントを配線
54
+ ai-notify use <名前> [声] [音量] # このペインの名前+声+タブ名を一括設定
54
55
  ai-notify toggle | on | off | status # ミュートスイッチ
55
56
  ai-notify volume [0.0-2.0] # 音量の取得/設定
56
57
  ai-notify voice [number|name|preview|default] # 読み上げ音声を選ぶ
@@ -62,6 +63,18 @@ ai-notify doctor # 依存・配線の確認
62
63
  ai-notify uninstall # 配線をきれいに削除
63
64
  ```
64
65
 
66
+ **ペインの設定を1コマンドで。** エージェントを動かす端末の中でこれを実行すると、読み上げ名・声・音量・**ターミナルのタブ名**を一度に設定できます。メニュー操作は不要:
67
+
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 zunda ずんだもん # 声は VOICEVOX キャラ名で指定(vv3 でも可)
72
+ ai-notify use エックスズンダモン ずんだもん --tab x_zunda # 読み上げ名とタブ名を別々に
73
+ ai-notify use clear # このペインをリセット
74
+ ```
75
+
76
+ `声` は `say` の名前/番号(`Kyoko`・`3`)、VOICEVOX の**キャラ名**(`ずんだもん`)、`vv<id>`(`vv3`)が使えます。`--tab` で読み上げ名と別のタブ名を付けられます。
77
+
65
78
  ペイン別の上書き — エージェントを起動する**前**に、その端末で `export` する:
66
79
 
67
80
  ```sh
package/README.md CHANGED
@@ -52,6 +52,7 @@ Adding another agent (aider, opencode, amp, …) is a small PR: drop a file in `
52
52
 
53
53
  ```sh
54
54
  ai-notify init [--dry-run] [--only claude,codex] # wire detected agents
55
+ ai-notify use <name> [voice] [vol] # set THIS pane's name + voice + tab title, in one go
55
56
  ai-notify toggle | on | off | status # the mute switch
56
57
  ai-notify volume [0.0-2.0] # get/set output volume
57
58
  ai-notify voice [number|name|preview|default] # pick the spoken voice
@@ -63,6 +64,18 @@ ai-notify doctor # check deps & wiring
63
64
  ai-notify uninstall # cleanly remove wiring
64
65
  ```
65
66
 
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
+
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 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
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
+
66
79
  Per-window overrides — `export` these in a terminal *before* launching the agent:
67
80
 
68
81
  ```sh
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ai-notify",
3
- "version": "0.4.6",
3
+ "version": "0.4.8",
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
@@ -6,7 +6,7 @@ import { readFileSync } from 'node:fs';
6
6
  import { execSync, execFileSync } from 'node:child_process';
7
7
  import { providers, byId } from './providers/index.mjs';
8
8
  import { emit } from './notify.mjs';
9
- import { deriveLabel, cliInvocation, isEphemeralInstall } from './util.mjs';
9
+ import { deriveLabel, cliInvocation, isEphemeralInstall, controllingTty } from './util.mjs';
10
10
  import { curatedVoices, resolveVoice, previewVoice } from './voices.mjs';
11
11
  import * as menubar from './menubar.mjs';
12
12
  import { translate } from './translate.mjs';
@@ -506,6 +506,89 @@ const cmds = {
506
506
  log(`pane ${tty}: name ${arg}`);
507
507
  },
508
508
 
509
+ // One-shot per-pane setup, run INSIDE the pane: set its spoken name, voice,
510
+ // and volume — and rename the terminal tab — in a single command, instead of
511
+ // doing each from the menu bar. Keyed by this shell's tty (which the agent's
512
+ // hook resolves to as well), so it just works for the agent running here.
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>).
516
+ use() {
517
+ const tty = controllingTty();
518
+ if (!tty) {
519
+ console.error('`ai-notify use` must run inside a terminal pane (no controlling tty found).');
520
+ process.exit(1);
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;
535
+ if (!name || name === 'clear' || name === 'reset') {
536
+ updatePaneSetting(tty, { speakName: null, tts: null, voice: null, speaker: null, volume: null });
537
+ process.stdout.write('\u001b]0;\u0007'); // clear the tab title (best-effort)
538
+ return log(`✓ pane reset (${tty})`);
539
+ }
540
+
541
+ const patch = { speakName: name };
542
+ let voiceLabel = '';
543
+ if (voiceArg !== undefined) {
544
+ const vv = /^(?:vv|voicevox):?(\d+)$/i.exec(voiceArg);
545
+ if (vv) {
546
+ patch.tts = 'voicevox';
547
+ patch.speaker = Number(vv[1]);
548
+ patch.voice = null;
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;
555
+ } else {
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
+ );
566
+ process.exit(1);
567
+ }
568
+ patch.tts = 'voicevox';
569
+ patch.speaker = hit.id;
570
+ patch.voice = null;
571
+ voiceLabel = `${hit.name} (VOICEVOX ${hit.id})`;
572
+ }
573
+ }
574
+ if (volArg !== undefined) {
575
+ const v = Number(volArg);
576
+ if (Number.isFinite(v)) patch.volume = Math.min(2, Math.max(0, v));
577
+ }
578
+
579
+ updatePaneSetting(tty, patch);
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`);
584
+
585
+ const bits = [`name ${name}`];
586
+ if (voiceLabel) bits.push(`voice ${voiceLabel}`);
587
+ if (patch.volume !== undefined) bits.push(`volume ${patch.volume}`);
588
+ bits.push(`tab ${tab}`);
589
+ log(`✓ ${bits.join(' · ')}`);
590
+ },
591
+
509
592
  // Get/set the VOICEVOX base prosody (the normal-tone scales the menu bar
510
593
  // sliders drive). With no args, prints the current values as JSON.
511
594
  // voice-prosody [speed|pitch|intonation <value> | reset]
@@ -710,6 +793,7 @@ function printHelp() {
710
793
  Usage:
711
794
  ai-notify init [--dry-run] [--only claude,codex] wire detected agents
712
795
  ai-notify uninstall [--only ...] remove wiring
796
+ ai-notify use <name> [voice] [vol] [--tab <t>] name THIS pane + voice + tab, at once (voice: Kyoko | 3 | ずんだもん | vv3)
713
797
  ai-notify toggle | on | off | status control the mute switch
714
798
  ai-notify volume [0.0-2.0] get/set output volume
715
799
  ai-notify voice [number|name|preview|default] pick the spoken voice