Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,7 @@
./hosts.allow
./hosts.deny
config/nvim/lazy-lock.json
config/nvim/log
zshrc.local
# Claude Code: machine-local / company-internal config must never be tracked (public repo)
claude/settings.local.json
66 changes: 66 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
# CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

## Overview

Personal dotfiles and Docker-based development environment for vankichi. The repo serves two purposes:
1. Dotfiles (zsh, tmux, git, neovim, starship) symlinked to `$HOME`
2. Multi-stage Docker images that assemble a full dev container (Go, Rust, Dart, K8s tools, etc.)

## Key Commands

```bash
# Symlink dotfiles to $HOME (uses ~/.config paths)
make new_link

# Remove symlinks
make new_clean

# Build the main dev container image
make build # simple docker build
make prod_build # multiplatform buildx (linux/amd64,linux/arm64)

# Build individual layer images
make build_go # reads versions/GO_VERSION
make build_rust
make build_env # reads versions/NGT_VERSION, TENSORFLOW_C_VERSION
make build_k8s
make build_base
make build_all # builds all layers then prod

# Update version files from upstream releases
make version/go
make version/ngt
make version/tensorflow
make version/flutter

# Run / manage the dev container (defined in alias file)
source ./alias && devrun # or just: make run
devin # exec into running container
devkill # stop and remove container
devres # kill + rerun

# Multiplatform buildx setup
make init_buildx # register qemu binfmt
make create_buildx # create buildx builder "vankichi-builder"
```

## Architecture

- **Dockerfile** — Final dev image. Multi-stage: pulls from `vankichi/{go,rust,docker,dart,kube,env}` images, copies binaries, then installs dotfiles.
- **dockers/** — Individual Dockerfiles for each layer image (base, env, go, rust, k8s, docker, dart, gcloud, glibc, nim).
- **versions/** — Plain text files (e.g., `GO_VERSION`) consumed as `--build-arg` during Docker builds. Updated via `make version/*` targets.
- **Makefile.d/version.mk** — Version-fetching targets, included by the main Makefile.
- **alias** — Shell functions (`devrun`, `devin`, `devkill`) for container lifecycle. `devrun` mounts dotfiles, Go src, Docker socket, SSH keys, etc. into the container; platform-aware (macOS vs Linux).
- **config/nvim/** — Lua-based Neovim config (lazy.nvim plugin manager).
- **config/sheldon/plugins.toml** — Sheldon zsh plugin manager config.

## Docker Image Hierarchy

```
base.Dockerfile → env.Dockerfile → Dockerfile (final)
↑ copies from: go, rust, docker, dart, kube
```

All images are pushed to Docker Hub under the `vankichi/` namespace. Builds use `docker buildx` for multiplatform support (`linux/amd64,linux/arm64`).
14 changes: 2 additions & 12 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ ENV CARGO_PATH $HOME/.cargo
ENV NVIM_HOME $HOME/.config/nvim
ENV VIM_PLUG_HOME $NVIM_HOME/plugged/vim-plug
ENV LIBRARY_PATH /usr/local/lib:$LIBRARY_PATH
ENV ZPLUG_HOME $HOME/.zplug
# ENV ZPLUG_HOME $HOME/.zplug
ENV PATH $GOPATH/bin:/usr/local/go/bin:$CARGO_PATH/bin:$DART_PATH/bin:$GCLOUD_PATH/bin:$PATH
Comment on lines 28 to 32

COPY --from=docker /usr/lib/docker/cli-plugins/docker-buildx /usr/lib/docker/cli-plugins/docker-buildx
Expand All @@ -49,16 +49,11 @@ COPY --from=go /go/bin $GOPATH/bin
COPY --from=rust /root/.cargo $CARGO_PATH
COPY --from=rust /root/.cargo/bin/rustup $HOME/.rustup

COPY coc-settings.json $NVIM_HOME/coc-settings.json
COPY efm-lsp-conf.yaml $NVIM_HOME/efm-lsp-conf.yaml
COPY gitattributes $HOME/.gitattributes
COPY gitconfig $HOME/.gitconfig
COPY gitignore $HOME/.gitignore
COPY init.vim $NVIM_HOME/init.vim
COPY monokai.vim $NVIM_HOME/colors/monokai.vim
COPY tmux-kube $HOME/.tmux-kube
COPY tmux.conf $HOME/.tmux.conf
COPY vintrc.yaml $HOME/.vintrc.yaml
COPY tmux.conf $HOME/.config/tmux/tmux.conf
COPY zshrc $HOME/.zshrc

ENV SHELL /usr/bin/zsh
Expand All @@ -75,12 +70,7 @@ RUN usermod -aG ${GROUP} ${WHOAMI} \
&& git clone --depth 1 https://github.com/junegunn/vim-plug.git $VIM_PLUG_HOME/autoload \
&& npm uninstall yarn -g \
&& npm install yarn -g \
&& yarn global add https://github.com/neoclide/coc.nvim --prefix /usr/local \
&& git clone --depth 1 https://github.com/zplug/zplug $ZPLUG_HOME \
&& zsh -ic zplug install \
&& rm -rf ${HOME}/.cache \
&& rm -rf ${HOME}/.zplug/cache/* \
&& rm -rf ${HOME}/.zplug/log/* \
&& rm -rf ${HOME}/.npm/_cacache \
&& rm -rf ${HOME}/.cargo/registry/cache \
&& rm -rf /usr/local/share/.cache \
Expand Down
111 changes: 65 additions & 46 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
.PHONY: all link clean zsh bash build prod_build profile run push pull update/go update/ngt
.PHONY: all new_link new_clean zsh bash build prod_build profile run push pull update/go update/ngt

include Makefile.d/version.mk

Expand All @@ -7,60 +7,78 @@ USER_ID = $(eval USER_ID := $(shell id -u $(USER)))$(USER_ID)
GROUP_ID = $(eval GROUP_ID := $(shell id -g $(USER)))$(GROUP_ID)
GROUP_IDS = $(eval GROUP_IDS := $(shell id -G $(USER)))$(GROUP_IDS)
ROOTDIR = $(eval ROOTDIR := $(or $(shell git rev-parse --show-toplevel), $(PWD)))$(ROOTDIR)

# $(ROOTDIR)/
all: prod_build login push profile git_push

run:
source ./alias && devrun

link:
mkdir -p ${HOME}/.config/nvim/colors
mkdir -p ${HOME}/.config/nvim/syntax
ln -sfv $(dir $(abspath $(lastword $(MAKEFILE_LIST))))init.vim $(HOME)/.config/nvim/init.vim
# ln -sfv $(dir $(abspath $(lastword $(MAKEFILE_LIST))))starship.toml $(HOME)/.config/starship.toml
# ln -sfv $(dir $(abspath $(lastword $(MAKEFILE_LIST))))efm-lsp-conf.yaml $(HOME)/.config/nvim/efm-lsp-conf.yaml
ln -sfv $(dir $(abspath $(lastword $(MAKEFILE_LIST))))coc-settings.json $(HOME)/.config/nvim/coc-settings.json
ln -sfv $(dir $(abspath $(lastword $(MAKEFILE_LIST))))monokai.vim $(HOME)/.config/nvim/colors/monokai.vim
# ln -sfv $(dir $(abspath $(lastword $(MAKEFILE_LIST))))go.vim $(HOME)/.config/nvim/syntax/go.vim
ln -sfv $(dir $(abspath $(lastword $(MAKEFILE_LIST))))zshrc $(HOME)/.zshrc
ln -sfv $(dir $(abspath $(lastword $(MAKEFILE_LIST))))editorconfig $(HOME)/.editorconfig
ln -sfv $(dir $(abspath $(lastword $(MAKEFILE_LIST))))alias $(HOME)/.aliases
ln -sfv $(dir $(abspath $(lastword $(MAKEFILE_LIST))))gitconfig $(HOME)/.gitconfig
ln -sfv $(dir $(abspath $(lastword $(MAKEFILE_LIST))))gitattributes $(HOME)/.gitattributes
ln -sfv $(dir $(abspath $(lastword $(MAKEFILE_LIST))))gitignore $(HOME)/.gitignore
ln -sfv $(dir $(abspath $(lastword $(MAKEFILE_LIST))))tmux.conf $(HOME)/.tmux.conf
ln -sfv $(dir $(abspath $(lastword $(MAKEFILE_LIST))))tmux-kube $(HOME)/.tmux-kube
# ln -sfv $(dir $(abspath $(lastword $(MAKEFILE_LIST))))tmux.new-session $(HOME)/.tmux.new-session

clean:
# sed -e "/\[\ \-f\ \$HOME\/\.aliases\ \]\ \&\&\ source\ \$HOME\/\.aliases/d" ~/.zshrc
unlink $(HOME)/.config/nvim/init.vim
# unlink $(HOME)/.config/starship.toml
# unlink $(HOME)/.config/nvim/efm-lsp-conf.yaml
unlink $(HOME)/.config/nvim/coc-settings.json
unlink $(HOME)/.config/nvim/colors/monokai.vim
# unlink $(HOME)/.config/nvim/syntax/go.vim
unlink $(HOME)/.zshrc
unlink $(HOME)/.editorconfig
unlink $(HOME)/.aliases
unlink $(HOME)/.gitconfig
unlink $(HOME)/.gitattributes
unlink $(HOME)/.gitignore
unlink $(HOME)/.tmux.conf
unlink $(HOME)/.tmux-kube
# unlink $(HOME)/.tmux.new-session

zsh: link
[ -f $(HOME)/.zshrc ] && echo "[ -f $$HOME/.aliases ] && source $$HOME/.aliases" >> $(HOME)/.zshrc

bash: link
[ -f $(HOME)/.bashrc ] && echo "[ -f $$HOME/.aliases ] && source $$HOME/.aliases" >> $(HOME)/.bashrc
unlink:
unlink $(HOME)/.config/nvim

new_link:
mkdir -p $(HOME)/.config
mkdir -p $(HOME)/.config/tmux
mkdir -p $(HOME)/.config/sheldon
ln -sfv $(shell pwd)/gitconfig $(HOME)/.gitconfig
ln -sfv $(shell pwd)/zshrc $(HOME)/.zshrc
[ -f $(shell pwd)/zshrc.local ] && ln -sfv $(shell pwd)/zshrc.local $(HOME)/.zshrc.local || true
ln -sfv $(shell pwd)/tmux.conf $(HOME)/.config/tmux/tmux.conf
ln -sfnv $(shell pwd)/config/nvim $(HOME)/.config/nvim
ln -sfv $(shell pwd)/starship.toml $(HOME)/.config/starship.toml
ln -sfv $(shell pwd)/config/sheldon/plugins.toml $(HOME)/.config/sheldon/plugins.toml
ln -sfv $(shell pwd)/editorconfig $(HOME)/.editorconfig
ln -sfv $(shell pwd)/alias $(HOME)/.aliases
ln -sfv $(shell pwd)/gitattributes $(HOME)/.gitattributes
ln -sfv $(shell pwd)/gitignore $(HOME)/.gitignore
ln -sfv $(shell pwd)/tmux-kube $(HOME)/.tmux-kube
# Claude Code config (runtime state stays local under ~/.claude)
mkdir -p $(HOME)/.claude
ln -sfv $(shell pwd)/claude/CLAUDE.md $(HOME)/.claude/CLAUDE.md
ln -sfv $(shell pwd)/claude/settings.json $(HOME)/.claude/settings.json
ln -sfv $(shell pwd)/claude/statusline-command.sh $(HOME)/.claude/statusline-command.sh
ln -sfnv $(shell pwd)/claude/agents $(HOME)/.claude/agents
ln -sfnv $(shell pwd)/claude/skills $(HOME)/.claude/skills
ln -sfnv $(shell pwd)/claude/hooks $(HOME)/.claude/hooks
ln -sfnv $(shell pwd)/claude/rules $(HOME)/.claude/rules
Comment thread
vankichi marked this conversation as resolved.

new_clean:
-unlink $(HOME)/.gitconfig
-unlink $(HOME)/.zshrc
-unlink $(HOME)/.zshrc.local
-unlink $(HOME)/.editorconfig
-unlink $(HOME)/.aliases
-unlink $(HOME)/.gitattributes
-unlink $(HOME)/.gitignore
-unlink $(HOME)/.tmux-kube
-unlink $(HOME)/.config/tmux/tmux.conf
-unlink $(HOME)/.config/nvim
-unlink $(HOME)/.config/starship.toml
-unlink $(HOME)/.config/sheldon/plugins.toml
-unlink $(HOME)/.claude/CLAUDE.md
-unlink $(HOME)/.claude/settings.json
-unlink $(HOME)/.claude/statusline-command.sh
-unlink $(HOME)/.claude/agents
-unlink $(HOME)/.claude/skills
-unlink $(HOME)/.claude/hooks
-unlink $(HOME)/.claude/rules

zsh: new_link
@if [ -f "$(HOME)/.zshrc" ] && ! grep -qF '[ -f $HOME/.aliases ] && source $HOME/.aliases' "$(HOME)/.zshrc"; then \
echo '[ -f $$HOME/.aliases ] && source $$HOME/.aliases' >> "$(HOME)/.zshrc"; \
fi

bash: new_link
@if [ -f "$(HOME)/.bashrc" ] && ! grep -qF '[ -f $HOME/.aliases ] && source $HOME/.aliases' "$(HOME)/.bashrc"; then \
echo '[ -f $$HOME/.aliases ] && source $$HOME/.aliases' >> "$(HOME)/.bashrc"; \
fi

build:
docker build -t vankichi/dev:latest .

docker_build:
docker build ${ARGS} --squash -t ${IMAGE_NAME}:latest -f ${DOCKERFILE} .
# docker build ${ARGS} --squash -t ${IMAGE_NAME}:latest -f ${DOCKERFILE} .
docker buildx build --platform $(DOCKER_BUILDER_PLATFORM) ${ARGS} --squash -t ${IMAGE_NAME}:latest -f ${DOCKERFILE} . --push
# docker buildx build --squash -t ${IMAGE_NAME}:latest -f ${DOCKERFILE} .
Comment thread
vankichi marked this conversation as resolved.

docker_push:
Expand Down Expand Up @@ -175,7 +193,8 @@ git_push:
DOCKER_EXTRA_OPTS = ""
DOCKER_BUILDER_NAME = "vankichi-builder"
DOCKER_BUILDER_DRIVER = "docker-container"
DOCKER_BUILDER_PLATFORM = "linux/amd64,linux/arm64/v8"
DOCKER_BUILDER_PLATFORM = "linux/amd64"
# DOCKER_BUILDER_PLATFORM = "linux/amd64,linux/arm64"

init_buildx:
docker run \
Expand Down
2 changes: 1 addition & 1 deletion Makefile.d/version.mk
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ version/go:
.PHONY: verison/ngt
## version/ngt
version/ngt:
@curl --silent https://api.github.com/repos/yahoojapan/NGT/releases/latest | grep -Po '"tag_name": "\K.*?(?=")' | sed 's/v//g' > $(ROOTDIR)/versions/NGT_VERSION
@curl --silent https://api.github.com/repos/NGT-labs/NGT/releases/latest | grep -Po '"tag_name": "\K.*?(?=")' | sed 's/v//g' > $(ROOTDIR)/versions/NGT_VERSION

.PHONY: version/tensorflow
## version/tensorflow
Expand Down
21 changes: 9 additions & 12 deletions alias
Original file line number Diff line number Diff line change
Expand Up @@ -50,19 +50,18 @@ function devrun {
-v $HOME/.netrc:$container_root/.netrc \
-v $HOME/.ssh:$container_root/.ssh \
-v $HOME/.gnupg:$container_root/.gnupg \
-v $HOME/.claude:$container_root/.claude \
-v $HOME/.claude.json:$container_root/.claude.json \
-v $HOME/Documents:$container_root/Documents \
-v $HOME/Downloads:$container_root/Downloads \
-v $HOME/go/src:/go/src:cached \
-v $docker_config:/etc/docker/config.json:ro,cached \
-v $docker_daemon:/etc/docker/daemon.json:ro,cached \
-v $font_dir:/usr/share/fonts:ro \
-v $rcpath/coc-settings.json:$container_root/.config/nvim/coc-settings.json \
-v $rcpath/editorconfig:$container_root/.editorconfig \
-v $rcpath/gitconfig:$container_root/.gitconfig \
-v $rcpath/gitignore:$container_root/.gitignore \
-v $rcpath/init.vim:$container_root/.config/nvim/init.vim \
-v $rcpath/monokai.vim:$container_root/.config/nvim/colors/monokai.vim \
-v $rcpath/tmux.conf:$container_root/.tmux.conf \
-v $rcpath/tmux.conf:$container_root/.config/tmux/tmux.conf \
-v $rcpath/zshrc:$container_root/.zshrc \
-v $rcpath/go.env:$container_goroot/go.env:ro \
-v $rcpath/go.env:$goroot/go.env:ro \
Expand Down Expand Up @@ -93,6 +92,11 @@ function devrun {
-v $HOME/.kube:$container_home/.kube \
-v $HOME/.netrc:$container_home/.netrc:ro \
-v $HOME/.ssh:$container_home/.ssh \
-v $HOME/.config:$container_home/.config:cached \
-v $HOME/.claude:$container_home/.claude:cached \
-v $HOME/.claude.json:$container_home/.claude.json \
-v /opt/claude-code:/opt/claude-code:ro \
-v /usr/bin/claude:/usr/local/bin/claude:ro \
-v $HOME/.zsh_history:$container_home/.zsh_history:cached \
-v $HOME/Documents:$container_home/Documents \
-v $HOME/Downloads:$container_home/Downloads \
Expand All @@ -101,19 +105,12 @@ function devrun {
-v $docker_daemon:$docker_daemon:ro,cached \
-v $docker_sock:$docker_sock \
-v $font_dir:$font_dir \
-v $rcpath/coc-settings.json:$container_home/.config/nvim/coc-settings.json \
-v $rcpath/editorconfig:$container_home/.editorconfig \
-v $rcpath/efm-lsp-conf.yaml:$container_home/.config/nvim/efm-lsp-conf.yaml \
-v $rcpath/gitattributes:$container_home/.gitattributes \
-v $rcpath/gitconfig:$container_home/.gitconfig \
-v $rcpath/gitignore:$container_home/.gitignore \
-v $rcpath/init.vim:$container_home/.config/nvim/init.vim \
-v $rcpath/monokai.vim:$container_home/.config/nvim/colors/monokai.vim \
-v $rcpath/tmux-kube:$container_home/.tmux-kube \
-v $rcpath/tmux.conf:$container_home/.tmux.conf \
-v $rcpath/nvim:$container_home/.config/nvim \
-v $rcpath/go.env:$container_goroot/go.env:ro \
-v $rcpath/go.env:$goroot/go.env:ro \
-v $rcpath/vintrc.yaml:$container_home/.vintrc.yaml \
-v $rcpath/zshrc:$container_home/.zshrc:ro,cached \
-v $tz_path:/etc/localtime:ro,cached \
-dit $image_name
Expand Down
57 changes: 57 additions & 0 deletions claude/CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# Global Claude Code Instructions

言語 / framework / project 固有の規約は project-local CLAUDE.md・`rules/`・各 skill 側で持つ。

## プロフィール

- Senior Software Engineer / AI Products 基盤開発
- 主戦場: Go / Typescript / Kubernetes / Docker
- security / governance / performance をコードの動作と同じ重さで扱う
- 説明は前提知識ありの深さで (基礎の言い直し不要)
- 思考 (thinking / reasoning) は英語
- user への出力は日本語 (コード内コメント・commit message は各規約に従う)

## 行動原則

- 迷ったら停止して user 確認
- security は「やってから謝る」より「やらずに聞く」
- secret (token / key / PII / 接続文字列 / 内部 URL) をコード・commit・log・出力の echo に書き込まない
- 既存ファイルで secret らしき文字列を見つけたら即停止して報告 (勝手に削除 / mask / commit しない)。commit 済みを検出したら push 前に flag、push 済みなら rotate を即提案
- least privilegepermission
- permission / IAM / RBAC / DB role / file mode は default deny。
- 一時的な拡大は独立 commit + 戻し計画 + 期限を提示してから
- `--no-verify` / `--force` / hook 無効化 / lint suppress / test skip は user の明示指示なしに使わない。hook / test / lint が落ちたら原因を直す
- 破壊的操作 (DB drop・広範囲 delete / git 履歴書き換え / infra・IAM・DNS 変更 / 公開 channel 送信 / public 公開) は **dry-run + 影響範囲 + 戻し方の 3 点セット** を提示し user 確認後のみ実行
- 新規 dependency 追加 / 外部送信 (telemetry / LLM API) の有効化 / service account・API key の発行は user 承認必須

## 判断と質問の作法

- 確定済みの判断は再質問しない。新規情報があった時のみ再考の必要性を 1 行で flag
- 機械的修正 / 既知 best practice は推奨を出して進める。設計判断・security / performance trade-off は user 判断を仰ぐ (新規発見の複数案は比較形式で提示)
- **plan-first**: 多ファイル refactor / 構造変更 / logic semantics 改訂 / 権限・secret・auth 変更 / performance 改修は、実装前に会話で合意 → `ExitPlanMode`。repo 内に plan markdown は書かない (ドキュメント化は user の明示指示時のみ)
- **plan / session state file の保存先**: 現在の project の *per-project plans dir* に置く = `~/.claude/projects/<encoded>/plans/`。`<encoded>` = cwd 絶対パスの `/` と `.` を `-` に置換したもの (= session に注入される memory dir と同じ階層の `plans/`)。global な `~/.claude/plans/` には新規に書かない。各 skill / agent はこの規約を参照して plan / state file の path を決める

## 変更の作法

- 指示外の変更 (対象外 file / 設定 / dependency / 計算量・I/O パターン) が発生したら、summary で **独立項目として列挙** し commit 前に user 承認を取る。「副次的に〜も修正」と埋め込まない
- TODO / FIXME を残したまま完了扱いにしない。security 関連の TODO は commit に残さない

## push / PR の作法

- push は user の literal 指示 (または `commit-push-branch` skill 経由) を待つ。「commit して」「amend して」は local 操作で stop し、push は提案だけする
- PR は自動作成しない (`gh pr create` は user 指示があれば別ターン)
- push 前に commit 内容を確認: secret / `.env` 系 / debug print / security TODO が含まれていたら止めて報告

## loop-mode (自律実行の例外規定)

- loop-mode = dev-cycle agent が spec (`rules/spec-contract.md` を満たす work item) を起点に自律実行する mode。人間の承認手続きを各工程の機械的 policy に置換する
- 例外として許可: `commit-push-branch` (loop-mode 拡張) 経由の feature branch push + **draft PR 作成**
- 引き続き禁止: merge / draft の本 PR 化 / main への直 push / 新規 dependency 追加 / 破壊的操作 / 外部送信の有効化 — 検出したら escalation (ticket コメント + 通知 + WIP branch push) して停止
- 安全装置 (hooks / permission deny / least privilege) は loop-mode でも一切緩めない
- superpowers 棲み分け: 自律 pipeline (dev loop) では superpowers の process skill を使わない (背骨は自前 skill)。対話 session での brainstorming / TDD 参照は可

## agent / skill 設計の原則

- project 固有用語 (repo 名 / service 名 / ticket prefix / 環境 URL / メンバー名) を agent / skill に hardcode しない。MEMORY.md の memory から取得する
- 新規 agent / skill / hook に `Bash(*)` 等の広範 permission を default で与えない。外部送信を含む skill は user 承認後に追加。hook で自動実行される command は user に明示してから commit
- **skill 粒度**: 1 skill = 1 責務。SKILL.md は薄い coordinator にし、観点 / checklist は `references/` に分割。発火条件は機械的 (grep / glob) に定義し、default-on + 理由付き skip + 全観点の実施状況出力を義務付ける
Loading