Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
9d9abf1
feat(claude): notify macOS Notification Center on Stop/Notification h…
rin2yh Jul 1, 2026
cfbb8c4
fix(claude): route CC_INVOCATION check through shell + rotate notify log
rin2yh Jul 1, 2026
3f2546a
fix(claude): strip broken UTF-8 tail from notify body
rin2yh Jul 1, 2026
fa73925
chore(nvim): pin mini.nvim, nvim-treesitter, ts-comments.nvim
rin2yh Jul 1, 2026
eee7b8c
chore(deps): bump nix-darwin from `56c666e` to `a1fa429`
dependabot[bot] Jul 3, 2026
fcd8106
chore(deps): bump homebrew-cask from `2a6d45e` to `5033334`
dependabot[bot] Jul 3, 2026
b2891a0
chore(deps): bump home-manager from `4c5c1e8` to `a4d410d`
dependabot[bot] Jul 3, 2026
d23d7e1
chore(deps): bump nix-homebrew from `aeb2069` to `de7953a`
dependabot[bot] Jul 3, 2026
55a98f3
chore(deps): bump homebrew-core from `458fc34` to `b420e2d`
dependabot[bot] Jul 3, 2026
5153947
fix(nvim/gopls): resolve TinyGo machine import via mise shim bypass
rin2yh Jul 5, 2026
5d1ac7d
chore(claude): lower default effort level to high
rin2yh Jul 5, 2026
e8303b8
refactor(nvim/gopls): drop :Tinygo wrapper; call :TinygoTarget directly
rin2yh Jul 6, 2026
9a402a8
refactor(nvim): split TinyGo autocmd into plugin/tinygo.lua
rin2yh Jul 6, 2026
17b8206
rename: plugin/tinygo.lua -> plugin/apply-tinygo.lua
rin2yh Jul 6, 2026
0a8c249
revert: keep TinyGo autocmd in lsp/gopls.lua
rin2yh Jul 6, 2026
ffc1780
Simplify: drop pcall closure wrapper, inline config_path
rin2yh Jul 6, 2026
798c36d
refactor(nvim): drop :Tinygo wrapper, split TinyGo autocmd into plugi…
rin2yh Jul 6, 2026
3434ebf
docs: add notes on when darwin-switch is required
rin2yh Jul 6, 2026
8d7f13e
chore(deps): bump homebrew-core from `458fc34` to `b420e2d` (#74)
rin2yh Jul 6, 2026
6b192a5
chore(deps): bump nix-homebrew from `aeb2069` to `de7953a` (#73)
rin2yh Jul 6, 2026
7ebc392
chore(deps): bump home-manager from `4c5c1e8` to `a4d410d` (#72)
rin2yh Jul 6, 2026
dabc9e9
chore(deps): bump homebrew-cask from `2a6d45e` to `5033334` (#71)
rin2yh Jul 6, 2026
4fb47eb
chore(deps): bump nix-darwin from `56c666e` to `a1fa429` (#70)
rin2yh Jul 6, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,13 @@ make help # Show available targets
├── home/ # home-manager 配下の各ツール設定
└── Makefile
```

## Notes

- `home/` 配下のファイルは `mkOutOfStoreSymlink` でリポジトリ実体への symlink として配置されている。既存ファイル(`.zshrc` / `nvim/` / `claude/CLAUDE.md` など)の内容だけを編集する場合、`darwin-rebuild switch` は不要で保存すれば即反映される。
- 以下のケースでは `make darwin-switch` が必要:
- `home/home.nix` の `home.packages` にパッケージを追加/削除
- `home.file` / `xdg.configFile` に新しい symlink エントリを追加
- `darwin/` 配下 (`configuration.nix` / `homebrew.nix` など) の変更
- `flake.nix` / `flake.lock` の更新
- `flake.lock` を更新する場合は `nix flake update` 後に `make darwin-switch`。
38 changes: 19 additions & 19 deletions flake.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

19 changes: 19 additions & 0 deletions home/claude/hooks/notify.applescript
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
on run
try
do shell script "test -n \"${CC_INVOCATION-}\""
on error
return
end try
try
set b to do shell script "printf %s \"${CC_BODY-}\""
on error
set b to ""
end try
try
set t to do shell script "printf %s \"${CC_TITLE-}\""
if t is "" then set t to "Claude Code"
on error
set t to "Claude Code"
end try
display notification b with title t
end run
47 changes: 47 additions & 0 deletions home/claude/hooks/notify.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
#!/usr/bin/env bash
set -euo pipefail

payload=$(cat)
(
sleep 0.5
IFS=$'\x1f' read -r event message cwd transcript <<< "$(jq -r '[.hook_event_name // "", .message // "", .cwd // "", .transcript_path // ""] | join("")' <<< "$payload")"

if [[ $cwd == */*/* ]]; then
parent=${cwd%/*}
title="${parent##*/}/${cwd##*/}"
else
title=${cwd##*/}
fi
: "${title:=Claude Code}"

case "$event" in
Stop)
body=""
if [ -f "$transcript" ]; then
body=$(tail -n 500 "$transcript" | tail -r | jq -r '
select(.type=="assistant" and .message.role=="assistant")
| .message.content
| if type=="string" then . else (map(select(.type=="text") | .text) | join(" ")) end
| gsub("^\\s+|\\s+$"; "")
| select(length > 0)
' 2>/dev/null | head -n 1 | tr '\n\r\t' ' ' | head -c 200 | { iconv -c -f UTF-8 -t UTF-8 2>/dev/null || true; })
fi
body=${body:-応答完了}
;;
Notification) body=${message:-入力待ち} ;;
"") exit 0 ;;
*) body=${message:-$event} ;;
esac

LOG=~/.cache/claude-notify.log
[ -f "$LOG" ] && [ "$(stat -f%z "$LOG" 2>/dev/null || echo 0)" -gt 1048576 ] && rm -f "$LOG"
printf '[%s] ppid=%s event=%s title=%s\n' \
"$(date +%Y-%m-%dT%H:%M:%S)" "$PPID" "${event:-<empty>}" "$title" \
>> "$LOG" 2>/dev/null || true

APP=$HOME/Applications/ClaudeCodeNotifier.app
if [ -x "$APP/Contents/MacOS/applet" ]; then
CC_INVOCATION=1 CC_BODY=$body CC_TITLE=$title "$APP/Contents/MacOS/applet" >/dev/null 2>&1
fi
) &
disown
26 changes: 25 additions & 1 deletion home/claude/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,30 @@
"defaultMode": "plan"
},
"model": "claude-opus-4-7[1m]",
"hooks": {
"Notification": [
{
"matcher": "",
"hooks": [
{
"type": "command",
"command": "/Users/yuuki/.claude/hooks/notify.sh"
}
]
}
],
"Stop": [
{
"matcher": "",
"hooks": [
{
"type": "command",
"command": "/Users/yuuki/.claude/hooks/notify.sh"
}
]
}
]
},
"statusLine": {
"type": "command",
"command": "~/.claude/statusline.js"
Expand Down Expand Up @@ -171,7 +195,7 @@
"gh"
]
},
"effortLevel": "xhigh",
"effortLevel": "high",
"showClearContextOnPlanAccept": true,
"autoUpdatesChannel": "latest",
"tui": "fullscreen",
Expand Down
30 changes: 30 additions & 0 deletions home/home.nix
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
{
config,
lib,
pkgs,
username,
...
Expand Down Expand Up @@ -67,6 +68,7 @@ in
config.lib.file.mkOutOfStoreSymlink "${dotfiles}/claude/statusline.js";
".claude/rules".source = config.lib.file.mkOutOfStoreSymlink "${dotfiles}/claude/rules";
".claude/skills".source = config.lib.file.mkOutOfStoreSymlink "${dotfiles}/claude/skills";
".claude/hooks".source = config.lib.file.mkOutOfStoreSymlink "${dotfiles}/claude/hooks";
};

xdg.configFile = {
Expand Down Expand Up @@ -100,6 +102,34 @@ in
# EDITOR = "emacs";
};

home.activation.claudeCodeNotifier = lib.hm.dag.entryAfter [ "writeBoundary" ] ''
APP="$HOME/Applications/ClaudeCodeNotifier.app"
ICON="/Applications/Claude.app/Contents/Resources/electron.icns"
SRC="${dotfiles}/claude/hooks/notify.applescript"

if [ ! -f "$ICON" ] || [ ! -f "$SRC" ]; then
exit 0
fi

if [ -x "$APP/Contents/MacOS/applet" ] \
&& [ ! "$SRC" -nt "$APP/Contents/MacOS/applet" ] \
&& [ ! "$ICON" -nt "$APP/Contents/Resources/applet.icns" ]; then
exit 0
fi

mkdir -p "$HOME/Applications"
rm -rf "$APP"
/usr/bin/osacompile -o "$APP" "$SRC"
rm -f "$APP/Contents/Resources/Assets.car"
cp "$ICON" "$APP/Contents/Resources/applet.icns"
/usr/bin/plutil -replace CFBundleIdentifier -string "dev.yuuki.claude-code-notifier" "$APP/Contents/Info.plist"
/usr/bin/plutil -replace CFBundleName -string "Claude Code" "$APP/Contents/Info.plist"
/usr/bin/plutil -remove CFBundleIconName "$APP/Contents/Info.plist" 2>/dev/null || true
/usr/bin/codesign --sign - --force --deep "$APP" >/dev/null 2>&1 || true
/System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/LaunchServices.framework/Versions/A/Support/lsregister -f "$APP" >/dev/null 2>&1 || true
/usr/bin/touch "$APP"
'';

# Let Home Manager install and manage itself.
programs.home-manager.enable = true;
}
30 changes: 28 additions & 2 deletions home/nvim/lua/lsp/gopls.lua
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
local M = {}

M.cmd = { 'gopls' }
M.filetypes = { 'go', 'gomod'}
-- mise の go shim は GOROOT env を無視するため、直接の go binary を PATH 先頭に
-- 置いてから gopls を起動する(gopls 内部の `go env` に TinyGo overlay を反映)。
local go_dir = vim.fs.dirname(vim.trim(vim.fn.system('mise which go')))
M.cmd = { 'env', 'PATH=' .. go_dir .. ':' .. vim.env.PATH, 'gopls' }
M.filetypes = { 'go', 'gomod' }
M.root_markers = { 'go.mod' }

M.settings = {
gopls = {
Expand All @@ -25,4 +29,26 @@ M.settings = {
}
}

-- sago35/tinygo.vim の `:TinygoTarget` を .tinygo.json 検出時に自動実行する。
-- `:TinygoTarget` は内部で GOROOT/GOOS/GOARCH/GOFLAGS を gopls の cmd_env に書き込み、
-- `vim.lsp.enable('gopls', false → true)` で gopls を再起動する。
vim.pack.add({ 'https://github.com/sago35/tinygo.vim' })

-- キャッシュしないと FileType go の度に `:TinygoTarget` が走り、gopls が毎回再起動する。
local applied = {}
vim.api.nvim_create_autocmd('FileType', {
pattern = 'go',
group = vim.api.nvim_create_augroup('tinygo-auto', {}),
callback = function(args)
local root = vim.fs.root(args.buf, '.tinygo.json')
if not root then return end
local ok, cfg = pcall(vim.json.decode,
table.concat(vim.fn.readfile(vim.fs.joinpath(root, '.tinygo.json')), '\n'))
if not ok or type(cfg) ~= 'table' or not cfg.target then return end
if applied[root] == cfg.target then return end
applied[root] = cfg.target
vim.cmd({ cmd = 'TinygoTarget', args = { cfg.target } })
end,
})

return M
36 changes: 0 additions & 36 deletions home/nvim/lua/lsp/init.lua
Original file line number Diff line number Diff line change
@@ -1,41 +1,5 @@
-- config of lsp

local safely = MiniMisc.safely

safely('now', function()
vim.pack.add({ 'https://github.com/pcolladosoto/tinygo.nvim' })
local tinygo = require("tinygo")
tinygo.setup({})

-- tinygo.nvim の applyConfigFile は .tinygo.json を相対パスで開くため、
-- nvim の cwd がプロジェクト外だと検出漏れする。バッファから上向き探索し
-- 絶対パスで読み取って TinyGoSetTarget を直接呼ぶ。
tinygo.applyConfigFile = function()
local bufname = vim.api.nvim_buf_get_name(0)
local search_path = nil
if bufname ~= "" then
search_path = vim.fs.dirname(bufname)
end
local found = vim.fs.find(tinygo.config_file, {
upward = true,
path = search_path,
})
if vim.tbl_isempty(found) then return end
local f = io.open(found[1], "r")
if f == nil then return end
local raw = f:read("a")
f:close()
local ok, cfg = pcall(vim.json.decode, raw)
if not ok or type(cfg) ~= "table" or cfg.target == nil then return end
vim.cmd.TinyGoSetTarget(cfg.target)
end

-- applyConfigFile は vim.lsp.enable(lsp_names) より後に走らせる必要がある。
-- tinygo.setup() で登録される LspAttach autocmd が gopls attach 時に拾って
-- くれるが、取りこぼし保険として main 完了後にも明示実行する。
vim.schedule(function() pcall(tinygo.applyConfigFile) end)
end)

vim.diagnostic.config({
virtual_text = true,
})
Expand Down
18 changes: 15 additions & 3 deletions home/nvim/nvim-pack-lock.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,17 @@
"rev": "a04ad0dbc725134edbee3a5eea29290976695357",
"src": "https://github.com/kdheepak/lazygit.nvim"
},
"tinygo.nvim": {
"rev": "0f38894d50ad5a02aae8f3df14a24576acc304f1",
"src": "https://github.com/pcolladosoto/tinygo.nvim"
"mini.nvim": {
"rev": "dc8a9918c3b1bc18a5fcd04d39b6d658074c0886",
"src": "https://github.com/echasnovski/mini.nvim"
},
"nvim-treesitter": {
"rev": "4916d6592ede8c07973490d9322f187e07dfefac",
"src": "https://github.com/nvim-treesitter/nvim-treesitter"
},
"tinygo.vim": {
"rev": "b95273ec07487cd59deed241b77d40e520fa08e7",
"src": "https://github.com/sago35/tinygo.vim"
},
"toggleterm.nvim": {
"rev": "9a88eae817ef395952e08650b3283726786fb5fb",
Expand All @@ -16,6 +24,10 @@
"rev": "cdc07ac78467a233fd62c493de29a17e0cf2b2b6",
"src": "https://github.com/folke/tokyonight.nvim"
},
"ts-comments.nvim": {
"rev": "a59d6092213447450191122c9346f309161504cb",
"src": "https://github.com/folke/ts-comments.nvim"
},
"vimdoc-ja": {
"rev": "ee16ecb8f802287302ff0317e52e27c274c16194",
"src": "https://github.com/vim-jp/vimdoc-ja"
Expand Down