Initial commit

This commit is contained in:
Zhongwei Li
2025-11-29 18:00:39 +08:00
commit 8457d2c114
12 changed files with 736 additions and 0 deletions

View File

@@ -0,0 +1,17 @@
{
"name": "takushi-notifier",
"description": "Claude Assistantの応答を音声で読み上げるプラグインStyle-Bert-VITS2対応",
"version": "1.0.0",
"author": {
"name": "Yuri"
},
"skills": [
"./skills"
],
"commands": [
"./commands"
],
"hooks": [
"./hooks"
]
}

3
README.md Normal file
View File

@@ -0,0 +1,3 @@
# takushi-notifier
Claude Assistantの応答を音声で読み上げるプラグインStyle-Bert-VITS2対応

51
commands/project_name.md Normal file
View File

@@ -0,0 +1,51 @@
---
description: "現在のプロジェクトに名前を設定する"
argument-hint: [project_name]
---
# エージェント向け指示
引数がある場合は現在の作業ディレクトリにプロジェクト名を設定し、引数がない場合は現在設定されているプロジェクト名を表示してください。
```bash
# プロジェクト名設定(引数がある場合)
bash "${CLAUDE_PLUGIN_ROOT}/hooks/project_manager.sh" set "$(pwd)" "[project_name]"
# 現在のプロジェクト名取得(引数がない場合)
bash "${CLAUDE_PLUGIN_ROOT}/hooks/project_manager.sh" get "$(pwd)"
```
---
# ユーザー向け使用方法
## 概要
現在のプロジェクトに名前を設定します。設定した名前は通知時に読み上げられます。
## 使用例
```bash
# プロジェクト名を設定
/project_name TakushiNotifier
# 現在のプロジェクト名を確認
/project_name
```
## 引数
- `project_name` (オプション): プロジェクトに付ける名前(文字列)
- 省略時: 現在のプロジェクト名を表示
## 動作
プロジェクト名が設定されている場合、通知時に読み上げるテキストの先頭に「{プロジェクト名}です。」が追加されます。
**例:**
- プロジェクト名: `InfoComposer`
- 元のメッセージ: `処理が完了しました。`
- 読み上げ: `InfoComposerです。処理が完了しました。`
## 設定保存
設定は `~/.config/takushi_notifier/project_names.conf` に保存され、プロジェクトパスごとに管理されます。

45
commands/volume.md Normal file
View File

@@ -0,0 +1,45 @@
---
description: "Takushi音量を0-100の範囲で設定する"
argument-hint: [volume]
---
# エージェント向け指示
引数がある場合は音量を設定し、引数がない場合は現在の音量を表示してください。
```bash
# 音量設定(引数がある場合)
bash "${CLAUDE_PLUGIN_ROOT}/hooks/volume_manager.sh" set [volume]
# 現在の音量取得(引数がない場合)
bash "${CLAUDE_PLUGIN_ROOT}/hooks/volume_manager.sh" get
```
---
# ユーザー向け使用方法
## 概要
TakushiText-to-Speechの音量を0-100の範囲で設定します。
## 使用例
```bash
# 音量を75%に設定
/volume 75
# 現在の音量を確認
/volume
```
## 引数
- `volume` (オプション): 音量レベル0-100の整数
- 0: 無音
- 50: 中間音量
- 100: 最大音量
- 省略時: 現在の音量を表示
## 設定保存
設定は `~/.config/takushi_notifier/volume.conf` に保存されます。

81
hooks/generate_message.sh Executable file
View File

@@ -0,0 +1,81 @@
#!/bin/bash
# メッセージ生成スクリプト
# プラグインのディレクトリを取得
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
HOOKS_DIR="$SCRIPT_DIR"
NOTIFY_LOG_PATH="$HOOKS_DIR/notify.log"
# 標準入力からメッセージ要約を取得
SUMMARY=$(cat)
EXISTING_EXAMPLES=$(cat <<'EOT'
- 対応を完了しました。
- 修正を反映しました。
- 最終確認をお願いします。
- 確認事項があります。
- 次の点についてご確認ください。
- ご回答をお願いします。
- 追加の情報が必要です。
- ご指示をお願いします。
- ご確認ください。
- 以上です。
EOT
)
# 直近10件のログを取得
RECENT_LOGS=""
if [ -f "$NOTIFY_LOG_PATH" ]; then
RECENT_LOGS=$(tail -n 10 "$NOTIFY_LOG_PATH" | cut -d'|' -f2)
fi
# Claude APIへのプロンプトを作成
PROMPT="あなたは無個性で中立的なアシスタントです。以下のタスク要約に対し、
感情やキャラクター性を排した、簡潔で平易な敬体のメッセージを50文字以内で生成してください。
前提: これはAgentからユーザーへの切り替え時の発言です質問がある時または対応完了時
タスク要約: $SUMMARY
【必須要件】
- 無個性・中立。感情やキャラクター性を出さない。
- です/ます調。過度に仰々しい敬語や比喩は避ける。
- 記号・絵文字・感嘆符を使わない。平易な語彙を用いる。
- 着手・開始・実行・進める等の未来時制の表現は使わない。
- 成果の報告または質問の提示に限定する。
【重複回避】
- 最近の発言(下記)と同義反復や語句の重複を避ける。
$RECENT_LOGS
【発言パターン例】
$EXISTING_EXAMPLES
【出力形式】
- 何をしたかが具体的にわかるよう、端的に記載する(前後の解説・記号・引用符なし)。"
# フォールバック文言の判定(質問/確認が含まれるかで出し分け)
if echo "$SUMMARY" | grep -Eq '[\?]|質問|確認|教えて|不明点|ご回答'; then
FALLBACK_MESSAGE="ご確認をお願いします。"
else
FALLBACK_MESSAGE="対応を完了しました。"
fi
# Claude CLIコマンドを使用してメッセージ生成
if command -v claude >/dev/null 2>&1; then
# プロンプトを直接パイプで渡す
RESPONSE=$(echo "$PROMPT" | claude -p - 2>/dev/null)
# レスポンスが取得できた場合
if [ -n "$RESPONSE" ] && [ "$RESPONSE" != "" ]; then
echo "$RESPONSE" | head -n 2
else
# Claude CLIが失敗した場合のフォールバック
echo "$FALLBACK_MESSAGE"
fi
else
# Claude CLIが利用できない場合のフォールバック
echo "$FALLBACK_MESSAGE"
fi

15
hooks/hooks.json Normal file
View File

@@ -0,0 +1,15 @@
{
"hooks": {
"Stop": [
{
"matcher": "",
"hooks": [
{
"type": "command",
"command": "${CLAUDE_PLUGIN_ROOT}/hooks/notify.sh"
}
]
}
]
}
}

90
hooks/notify.sh Executable file
View File

@@ -0,0 +1,90 @@
#!/bin/bash
# 音声通知スクリプト
# 最後のメッセージを取得し、要約してメッセージを読み上げ
# 標準入力からJSONを読み取る
INPUT=$(cat)
# プラグインのディレクトリを取得
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PLUGIN_DIR="$(dirname "$SCRIPT_DIR")"
HOOKS_DIR="$SCRIPT_DIR"
NOTIFY_LOG_PATH="$HOOKS_DIR/notify.log"
# ログディレクトリの作成
mkdir -p "$HOOKS_DIR"
# トランスクリプトを処理(.jsonl形式に対応
TRANSCRIPT_PATH=$(echo "$INPUT" | jq -r '.transcript_path')
if [ -f "$TRANSCRIPT_PATH" ]; then
# 最後のアシスタントメッセージのみを取得(全文)
TEMP_FILE=$(mktemp)
if command -v tail >/dev/null 2>&1; then
tail -r "$TRANSCRIPT_PATH" > "$TEMP_FILE"
LAST_MESSAGE=""
while IFS= read -r line; do
# JSON形式の妥当性をチェック
if echo "$line" | jq -e . >/dev/null 2>&1; then
if echo "$line" | jq -e '.type == "assistant"' >/dev/null 2>&1; then
LAST_MESSAGE=$(echo "$line" | jq -r '.message.content[]? | select(.type == "text") | .text' 2>/dev/null)
break
fi
fi
done < "$TEMP_FILE"
rm -f "$TEMP_FILE"
fi
# メッセージが取得できた場合の処理
if [ -n "$LAST_MESSAGE" ]; then
# 最後のメッセージの1行目を取得最大100文字
MESSAGE=$(echo "$LAST_MESSAGE" | head -n 1 | head -c 100 | sed 's/[[:space:]]*$//')
# メッセージが空の場合はデフォルト文例
if [ -z "$MESSAGE" ]; then
MESSAGE="処理が完了しました。"
fi
# プロジェクト名を取得して追加
PROJECT_PATH=$(echo "$INPUT" | jq -r '.cwd // empty')
if [ -n "$PROJECT_PATH" ]; then
PROJECT_MANAGER="$HOOKS_DIR/project_manager.sh"
if [ -f "$PROJECT_MANAGER" ]; then
PROJECT_NAME=$(bash "$PROJECT_MANAGER" get "$PROJECT_PATH" 2>/dev/null || echo "")
if [ -n "$PROJECT_NAME" ]; then
MESSAGE="${PROJECT_NAME}のたくしです。${MESSAGE}"
fi
fi
fi
# 通知実行
# terminal-notifier使用Macネイティブ通知
if command -v terminal-notifier >/dev/null 2>&1; then
terminal-notifier -message "$MESSAGE" -title "Assistant" >/dev/null 2>&1 &
fi
# 音声出力Style-Bert-VITS2
TTS_SCRIPT="$HOOKS_DIR/tts_bert_vits.sh"
if [ -f "$TTS_SCRIPT" ]; then
nohup bash "$TTS_SCRIPT" "$MESSAGE" >/dev/null 2>&1 &
fi
# ログ保存(タイムスタンプ|発言のみ、改行除去)
TIMESTAMP=$(date '+%Y-%m-%d %H:%M:%S')
CLEAN_MESSAGE=$(echo "$MESSAGE" | tr -d '\n\r' | sed 's/[[:space:]]\+/ /g' | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')
echo "$TIMESTAMP|$CLEAN_MESSAGE" >> "$NOTIFY_LOG_PATH"
# ログを10件までに制限
if [ -f "$NOTIFY_LOG_PATH" ]; then
TEMP_LOG=$(mktemp)
tail -n 10 "$NOTIFY_LOG_PATH" > "$TEMP_LOG"
mv "$TEMP_LOG" "$NOTIFY_LOG_PATH"
fi
fi
fi
echo '{"decision": "approve"}'
exit 0

126
hooks/project_manager.sh Executable file
View File

@@ -0,0 +1,126 @@
#!/bin/bash
# Takushiプロジェクト名管理スクリプト
# 使用方法: ./project_manager.sh [action] [args...]
# action: set, get, init
CONFIG_DIR="$HOME/.config/takushi_notifier"
PROJECT_NAMES_FILE="$CONFIG_DIR/project_names.conf"
# 設定ディレクトリの作成
init_config() {
mkdir -p "$CONFIG_DIR"
if [ ! -f "$PROJECT_NAMES_FILE" ]; then
touch "$PROJECT_NAMES_FILE"
fi
}
# プロジェクト名設定
set_project_name() {
local project_path="$1"
local project_name="$2"
# 引数チェック
if [ -z "$project_path" ] || [ -z "$project_name" ]; then
echo "エラー: プロジェクトパスと名前を指定してください"
exit 1
fi
init_config
# 一時ファイルを作成
local temp_file=$(mktemp)
local var_name="PROJECT_NAME_${project_path//\//_}"
local updated=false
# 設定ファイルを読み込み、該当行を更新
if [ -f "$PROJECT_NAMES_FILE" ]; then
while IFS= read -r line; do
if [[ "$line" =~ ^${var_name}= ]]; then
echo "${var_name}=\"$project_name\"" >> "$temp_file"
updated=true
else
echo "$line" >> "$temp_file"
fi
done < "$PROJECT_NAMES_FILE"
fi
# 新規追加の場合
if [ "$updated" = false ]; then
echo "${var_name}=\"$project_name\"" >> "$temp_file"
fi
# 一時ファイルで設定ファイルを上書き
mv "$temp_file" "$PROJECT_NAMES_FILE"
echo "プロジェクト「${project_name}」を設定しました (パス: ${project_path})"
}
# プロジェクト名取得
get_project_name() {
local project_path="$1"
if [ -z "$project_path" ]; then
echo "エラー: プロジェクトパスを指定してください"
exit 1
fi
init_config
if [ -f "$PROJECT_NAMES_FILE" ]; then
local current_path="$project_path"
# 現在のパスから親階層まで順に探索
while [ -n "$current_path" ]; do
local var_name="PROJECT_NAME_${current_path//\//_}"
local project_name=$(grep "^${var_name}=" "$PROJECT_NAMES_FILE" | cut -d'=' -f2- | tr -d '"')
if [ -n "$project_name" ]; then
echo "$project_name"
return
fi
# 親ディレクトリに移動
if [ "$current_path" = "/" ] || [ "$current_path" = "." ]; then
break
fi
current_path=$(dirname "$current_path")
if [ "$current_path" = "." ]; then
break
fi
done
fi
echo ""
}
# メイン処理
case "${1:-get}" in
"set")
if [ -z "$2" ] || [ -z "$3" ]; then
echo "エラー: プロジェクトパスと名前を指定してください"
echo "使用方法: $0 set [path] [name]"
exit 1
fi
set_project_name "$2" "$3"
;;
"get")
if [ -z "$2" ]; then
echo "エラー: プロジェクトパスを指定してください"
echo "使用方法: $0 get [path]"
exit 1
fi
get_project_name "$2"
;;
"init")
init_config
echo "設定ディレクトリを初期化しました: $CONFIG_DIR"
;;
*)
echo "使用方法: $0 [set|get|init] [args...]"
echo " set [path] [name] : プロジェクト名を設定"
echo " get [path] : プロジェクト名を取得"
echo " init : 設定ディレクトリを初期化"
exit 1
;;
esac

107
hooks/tts_bert_vits.sh Executable file
View File

@@ -0,0 +1,107 @@
#!/bin/bash
# Style-Bert-VITS2 音声合成スクリプト
# 使用方法: ./tts_bert_vits.sh "読み上げたいテキスト"
# API認証情報
CF_ACCESS_CLIENT_ID="78daf18f4b82f77f12a0bfec004ab4ce.access"
CF_ACCESS_CLIENT_SECRET="cded896f04ee01c47f5098cebcd3118ed09ad1bc3666f1d59cc5912b2e724020"
API_BASE_URL="https://bert-vits-web.vildas.org"
# モデル設定(固定)
MODEL_NAME="izawa_toiyomi"
MODEL_FILE="model_assets/izawa_toiyomi/izawa_toiyomi_e100_s5000.safetensors"
# 設定ファイルの読み込み
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# グローバル設定ファイルを読み込み
GLOBAL_CONFIG="$HOME/.config/takushi_notifier/volume.conf"
# グローバル設定ファイルが存在する場合は読み込み
if [ -f "$GLOBAL_CONFIG" ]; then
. "$GLOBAL_CONFIG"
fi
# 音量設定(設定ファイルで AFPLAY_VOLUME を 0.0〜1.0 で指定可能。)
AFPLAY_VOLUME="${AFPLAY_VOLUME:-1.0}"
# 引数チェック
if [ $# -eq 0 ]; then
echo "エラー: テキストを指定してください"
echo "使用方法: $0 \"読み上げたいテキスト\""
exit 1
fi
TEXT="$1"
SAVE_FILE="${2:-}" # 第2引数で出力ファイル名を指定可能省略時は一時ファイル
# 出力ファイルの設定
if [ -z "$SAVE_FILE" ]; then
# ファイル名が指定されていない場合は一時ファイルを使用macOS対応
OUTPUT_FILE=$(mktemp).wav
if [ $? -ne 0 ] || [ -z "$OUTPUT_FILE" ]; then
echo "エラー: 一時ファイルの作成に失敗しました"
exit 1
fi
TEMP_FILE=true
else
OUTPUT_FILE="$SAVE_FILE"
TEMP_FILE=false
fi
# 1. G2P処理でmoraToneListを取得
G2P_RESULT=$(curl -s -X POST "${API_BASE_URL}/api/g2p" \
-H "CF-Access-Client-Id: ${CF_ACCESS_CLIENT_ID}" \
-H "CF-Access-Client-Secret: ${CF_ACCESS_CLIENT_SECRET}" \
-H "Content-Type: application/json" \
-d "{\"text\": \"${TEXT}\"}")
# エラーチェック
if [ $? -ne 0 ]; then
echo "エラー: G2P処理に失敗しました"
exit 1
fi
# 2. 音声合成
SYNTHESIS_JSON=$(cat <<EOF
{
"model": "${MODEL_NAME}",
"modelFile": "${MODEL_FILE}",
"text": "${TEXT}",
"moraToneList": ${G2P_RESULT}
}
EOF
)
# 音声合成リクエスト
HTTP_STATUS=$(curl -s -X POST "${API_BASE_URL}/api/synthesis" \
-H "CF-Access-Client-Id: ${CF_ACCESS_CLIENT_ID}" \
-H "CF-Access-Client-Secret: ${CF_ACCESS_CLIENT_SECRET}" \
-H "Content-Type: application/json" \
-H "Accept: audio/wav" \
-d "${SYNTHESIS_JSON}" \
--output "${OUTPUT_FILE}" \
-w "%{http_code}")
# HTTPステータスコードチェック
if [ -n "$HTTP_STATUS" ] && [ "$HTTP_STATUS" -eq 200 ]; then
if [ -f "${OUTPUT_FILE}" ]; then
if [ "$TEMP_FILE" = true ]; then
# 一時ファイルの場合は自動再生して削除
afplay -v "${AFPLAY_VOLUME}" "${OUTPUT_FILE}"
rm "${OUTPUT_FILE}"
else
# ファイル保存の場合
echo "ファイル: ${OUTPUT_FILE}"
fi
fi
else
echo "エラー: 音声合成に失敗しました (HTTPステータス: ${HTTP_STATUS})"
if [ -f "${OUTPUT_FILE}" ]; then
echo "エラー内容:"
cat "${OUTPUT_FILE}"
rm "${OUTPUT_FILE}"
fi
exit 1
fi

85
hooks/volume_manager.sh Executable file
View File

@@ -0,0 +1,85 @@
#!/bin/bash
# Takushi音量管理スクリプト
# 使用方法: ./volume_manager.sh [action] [args...]
# action: set, get, init
CONFIG_DIR="$HOME/.config/takushi_notifier"
CONFIG_FILE="$CONFIG_DIR/volume.conf"
DEFAULT_VOLUME=50
# 設定ディレクトリの作成
init_config() {
mkdir -p "$CONFIG_DIR"
if [ ! -f "$CONFIG_FILE" ]; then
echo "AFPLAY_VOLUME=0.5" > "$CONFIG_FILE"
echo "VOLUME_PERCENT=$DEFAULT_VOLUME" >> "$CONFIG_FILE"
fi
}
# 音量設定0-100を0.0-1.0に変換)
set_volume() {
local volume_percent="$1"
# 引数チェック
if ! [[ "$volume_percent" =~ ^[0-9]+$ ]]; then
echo "エラー: 音量は0-100の整数で指定してください"
exit 1
fi
if [ "$volume_percent" -lt 0 ] || [ "$volume_percent" -gt 100 ]; then
echo "エラー: 音量は0-100の範囲で指定してください"
exit 1
fi
# 0-100を0.0-1.0に変換
local volume_float=$(echo "scale=2; $volume_percent / 100" | bc -l)
# 設定ファイルを更新
init_config
cat > "$CONFIG_FILE" << EOF
AFPLAY_VOLUME=$volume_float
VOLUME_PERCENT=$volume_percent
EOF
echo "Takushi音量を${volume_percent}%に設定しました (afplay: ${volume_float})"
}
# 現在の音量取得
get_volume() {
init_config
if [ -f "$CONFIG_FILE" ]; then
source "$CONFIG_FILE"
echo "現在のTakushi音量: ${VOLUME_PERCENT}% (afplay: ${AFPLAY_VOLUME})"
else
echo "設定ファイルが見つかりません。初期化します..."
init_config
echo "現在のTakushi音量: ${DEFAULT_VOLUME}% (afplay: 0.5)"
fi
}
# メイン処理
case "${1:-get}" in
"set")
if [ -z "$2" ]; then
echo "エラー: 音量を指定してください"
echo "使用方法: $0 set [0-100]"
exit 1
fi
set_volume "$2"
;;
"get")
get_volume
;;
"init")
init_config
echo "設定ディレクトリを初期化しました: $CONFIG_DIR"
;;
*)
echo "使用方法: $0 [set|get|init] [volume]"
echo " set [0-100] : 音量を設定"
echo " get : 現在の音量を表示"
echo " init : 設定ディレクトリを初期化"
exit 1
;;
esac

77
plugin.lock.json Normal file
View File

@@ -0,0 +1,77 @@
{
"$schema": "internal://schemas/plugin.lock.v1.json",
"pluginId": "gh:Baton8/TakushiNotifier:",
"normalized": {
"repo": null,
"ref": "refs/tags/v20251128.0",
"commit": "9d714c426edc813540942df2e77f080226ebfb55",
"treeHash": "eba7010f547c846e44250bc53c66282055258ed391d7fc3498aaa813d830b72b",
"generatedAt": "2025-11-28T10:09:57.127461Z",
"toolVersion": "publish_plugins.py@0.2.0"
},
"origin": {
"remote": "git@github.com:zhongweili/42plugin-data.git",
"branch": "master",
"commit": "aa1497ed0949fd50e99e70d6324a29c5b34f9390",
"repoRoot": "/Users/zhongweili/projects/openmind/42plugin-data"
},
"manifest": {
"name": "takushi-notifier",
"description": "Claude Assistantの応答を音声で読み上げるプラグインStyle-Bert-VITS2対応",
"version": "1.0.0"
},
"content": {
"files": [
{
"path": "README.md",
"sha256": "441e798aed35ed069950be361ffef7ed0759b81ad844e9e9a86001958ed43bfb"
},
{
"path": "hooks/tts_bert_vits.sh",
"sha256": "d7f0e178fdad527b359716c28db5fe78cf7425cd54f50062cefe6cbf3a05a3cc"
},
{
"path": "hooks/project_manager.sh",
"sha256": "388a6311af6cff1e8966f3357fe4689a70f6f1a81c2bc107ef0a550226b32f36"
},
{
"path": "hooks/generate_message.sh",
"sha256": "2ca89bb4821c2f455d5dca411ae5bfd548dfe915e76f04fc9d49407e68ed6cb6"
},
{
"path": "hooks/hooks.json",
"sha256": "93cd760da216581490d8b2d0547fa2326a33a67149408d881db972638dec1039"
},
{
"path": "hooks/volume_manager.sh",
"sha256": "32b85aa3eeff9a41aa225f50a699bf653df4564c54dabe87c04ee362b627e2e2"
},
{
"path": "hooks/notify.sh",
"sha256": "184d4f5bde3eee9f9ae9b9cc93471b39c4fa50f9161e8d3b6148e860d30a59af"
},
{
"path": ".claude-plugin/plugin.json",
"sha256": "83f1141f242789a8777158e2f722daad1e11a620511f549fa88c711c169e258a"
},
{
"path": "commands/volume.md",
"sha256": "6e6c7ab3fae2fba204e59b6df855f8f81e02b3a741876d403a591496377cecde"
},
{
"path": "commands/project_name.md",
"sha256": "3812393341bb68ac23259a556787f7f6e7758fe73a8b8d1db80bb812fcf60ed6"
},
{
"path": "skills/takushi-notification/SKILL.md",
"sha256": "65da5988c108770fffef0eb4ef6c3571c7a90766fdaa03be185a5757f3028ff6"
}
],
"dirSha256": "eba7010f547c846e44250bc53c66282055258ed391d7fc3498aaa813d830b72b"
},
"security": {
"scannedAt": null,
"scannerVersion": null,
"flags": []
}
}

View File

@@ -0,0 +1,39 @@
---
description: "Takushi通知機能の設定と使用方法を提供するスキル"
---
# Takushi通知スキル
このスキルは、Claude Assistantの応答を音声で読み上げる機能を提供します。
## 機能
- Assistantの応答を自動的に音声で読み上げ
- Style-Bert-VITS2を使用した高品質な音声合成
- メッセージの要約と動的生成
- 通知ログの管理
## 設定
### 音量設定
`/volume`コマンドで音量を調整できます:
```
/volume 50 # 50%の音量に設定
```
### API設定
`hooks/tts_bert_vits.sh`ファイル内で以下の設定を確認してください:
- CF_ACCESS_CLIENT_ID
- CF_ACCESS_CLIENT_SECRET
- API_BASE_URL
- MODEL_NAME
## 使用方法
プラグインをインストールすると、Assistantの応答が自動的に音声で読み上げられます。
## トラブルシューティング
- 音声が再生されない場合は、macOSの音量設定を確認してください
- APIエラーが発生する場合は、認証情報を確認してください
- ログは`hooks/notify.log`に保存されます