次の営業日取得ライブラリ、go-heijitu作った

経緯

毎月のルーチンワークで通知を飛ばす業務がある時、それを自動化しようと思ったら、 1月の年始とか、祝日に通知を飛ばすことを回避する必要があったので作る事にした。
特定月の最初の営業日とか曜日を取得できるGoのライブラリ。

https://github.com/taku-o/go-heijitu


翌月の最初の営業日の取得方法

go get github.com/taku-o/go-heijitu
package main

import (
    "context"
    "fmt"
    "time"

    heijitu "github.com/taku-o/go-heijitu"
    "github.com/taku-o/go-heijitu/providers/holidayjp"
)

func main() {
    ctx := context.Background()
    cal := heijitu.New(holidayjp.New())

    // 今日を基準に「来月の1日」を求める
    now := time.Now()
    nextMonth := now.AddDate(0, 1, 0) // 1ヶ月後

    // 来月の最初の営業日を取得
    day, err := cal.FirstBusinessDayOfMonth(ctx, nextMonth.Year(), nextMonth.Month())
    if err != nil {
            panic(err)
    }
    fmt.Println("来月の最初の営業日:", day.Format("2006-01-02"))
}


おわり

終わりです。
こういうのがサクサク作れる良い時代になった。

放送大学に入学してきた

少し前に放送大学に入ると学割がお得だよみたいな話題があって、
それを見て勢い余って放送大学に入学してしまった。4月から大学生です。
思い立ったのが2月20日過ぎ。授業の選択期限が2月末。
急ぎになってしまったので、授業は確実に単位が取れそうな一科目しか選べていない。


放送大学の入り方

4月入学、10月入学がある。
しかし授業の選択はもっと前にある。4月入学なら2月半ばには準備を始める必要があるか。


入学申請時に必要な書類・ファイル

  • 大学に入るに足る力量を示すもの。大学の卒業証明書がお手軽。
  • 顔写真の画像。
  • 証明書を郵送するための封筒。


入学申請時に登録する情報

  • 専門コース (生活と福祉、心理と教育、社会と産業、人間と文化、情報、自然と環境)
  • 受ける授業、1つ以上。授業の形態がいくつかある。インターネット、対面、Zoomなど。受けたい授業に対応出来るか事前に確認しておく必要がある。
  • 所属する学習センター。文京区とか渋谷とかに施設がある。駅からの近さとか確認しておいた方が良い。


必要な金額

  • 学割が必要なら全科履修生で入学する必要がある。
    • 入学金 24000円。
    • 授業料はものによるけれど、半年で6000円から。
  • 一度入学すると10年間所属できて、2年に1回は授業を1つは取る必要がある。
    • つまり、最低限必要な金額は10年で24000円 + 6000円 x 5 = 54000円。
    • 2年目時点だと24000円 + 6000円 = 30000円。
  • 振込手数料や郵送時の費用、交通費などは別に必要。
  • 興味のある授業をいくつか追加で取るなら、その分、お金はかかる。教科書代もかかる。


入学の手順 (インターネット出願)

  • 放送大学ホームページ https://www.ouj.ac.jp
  • 学生募集要項を読む。
  • 入学手続きに必要な書類を集める。
    • 大学の卒業証明書、は手に入れるのに少し時間がかかるはず。
    • 顔写真の画像、も手続き時にはあった方が良い。
  • インターネット出願する。
    • 整理番号とパスワードが発行される。このパスワードで出願申請進行状況確認画面にログインできる。
  • 大学の卒業証明書を封筒に入れて、封筒に送り先、整理番号、住所氏名、入学資格書類在中を書いてから、郵便局から簡易書留か一般書留で郵送する。
  • インターネット出願後、2週間弱で選考結果が出る。
    • 出願申請進行状況確認画面で確認するか、メールが送られてくるのを待つ。
  • 選考結果が郵送されてくる。
  • インターネットの出願申請進行状況確認画面に表示されるバーコードからお金を振り込む。
    • PayBを利用した。PayBアプリはいくつかある。銀行が対応しているか確認すること。
  • 入金情報が完納になる。
  • 教材が送られてくる。
  • 入学証明書が送られてくる。
  • パスワードを再設定後、WAKABAにログインする。この時点で大学のメールアドレスが入手できる。
  • Wifi利用申請
    • WAKABAで情報セキュリティ研修を受けて合格する。その後、無線LAN利用申請
    • セキュリティ研修が45分以上かかるので、学習センターに行く前に申請を済ませておく。
  • 所属している学習センターのGoogleカレンダーの予定を入手しておく。
  • 所属している学習センターで入学者の集いに参加申請する。
  • 学生証を受け取る。4/1以降。入学証明書が必要。


授業

  • 割と負荷がある。教科書をしっかり読み込むなら。
    • 自分だと1科目1週間くらいが継続可能な負荷か。
    • これを他に目移りする娯楽のある、在宅環境でやるわけだから、自分が現役でここで大学生活送ったなら卒業できなそうではある。
  • 単位を取るだけならどれくらいの負荷になるかは不明。


学割

  • 学割で節約は、当たり前だが、今支払いが発生していて、それが学割の対象でなければ節約することはできない。
  • 自分だと適用できた学割は今のところ、こんなところだが、事前調査で学割があるとされたものも実際やってみると学割が無かったりした。
* GitHub Education
    * GitHub Copilot (GitHub Education経由)
    * 1 Password (GitHub Education経由)
    * GitHub Pro (GitHub Education経由)
* Figma Education
* Amazon Prime
  • 今のところ、2年間換算だと少し足が出ているか。
    • 新規にMacを買うか、学割があるかないかよく分からないCursorの学割を通せば良さそうだ。
    • Adobe製品とか使っていれば良かったが、残念ながらFinal Cut Proに、Affinity派であった。


おわり

何はともあれ、新規に何かを始めるのは心が躍ります。
おわり。

install.shによるAIプロジェクトの初期セットアップ手法

こんな仕組みを考えてみた。

AI系のプロジェクトでは最初にたくさんのファイルを作る必要がある。
serenaとかセットアップする必要がある。

そこでinstall.shというのを用意して、その中でファイルをばら撒いたり、
セットアップ処理を行えば、AIプロジェクトの初期作業が楽になるかもなぁ、と。

curl -fsSL https://raw.githubusercontent.com/taku-o/ai-project-template/master/install.sh | sh

install.sh

install.shの中身はこんな感じです。
これを自分の好みの環境用にカスタマイズする。
https://github.com/taku-o/ai-project-template/blob/master/install.sh

#!/bin/bash
set -e

echo "Installing ai-project-template..."

git clone --depth 1 https://github.com/taku-o/ai-project-template.git ai-project-template
rm -rf ai-project-template/.git ai-project-template/README.md ai-project-template/install.sh
(cd ai-project-template; tar cf - .) | tar xpf -
rm -rf ai-project-template

echo "Done!"

おわり

おわり

Gemini CLIで手書きの図からDraw.ioの図を生成する

経緯

仕事でDraw.ioの図の作成を多用するので、Gemini CLIで手書きの図から Draw.ioの図を生成させたら、仕事早くなるよね、と考えました。
Twitterで流れてきた情報によると、これは実際出来るらしく。


用意した手書きの図

まずは、元となる手書きの図を用意します。


Gemini CLIにお願い (1回目)

draw_image.png は私の作成した手書きの図です。
この手書きの図の情報を参考に、表示を綺麗にしたDrawioのファイルを生成してください。
ファイルの拡張子は.drawioにしてください。


Gemini CLI回答:

この手書き図に描かれている「商品」「UI」「API」「DB」「認証」の要素とそれらの関係性を元に、Drawioファイルを生成します。
生成するファイル名はdrawio-diagram.drawio とします。


・・・なんだって?

全然違う。
どのように処理していたか見ていませんでしたが、 処理中に変なファイルを読んでしまったのかもしれないですね。


Gemini CLIにお願い (2回目)

環境をクリアにして、変なファイルを読み込まないように修正して、再トライ。
@マークを使って、読み込むファイルを教えることにしました。

@draw_image.png
このdraw_image.png は私の作成した手書きの図です。
この手書きの図を綺麗なDrawioのファイルにしたいです。
生成するファイルの拡張子は.drawioにしてください。


おしい


生成した図を修正させる

Gemini CLIに追加で修正させます。

生成した図を作り直して欲しいです。
矢印の根元は、Claude Codeの枠の左側、Gemini CLIの左側から生やして欲しい。
矢印の先っぽは、Kiro Taskの枠の右側につけてください。


なかなかの出来です。


Gemini CLIにお願い (3回目)

手書きの画像を渡すだけでなく、
図が表現している内容をテキストでも説明してみました。

・draw_image.png は私の作成した手書きの図です。
・図の内容は、
Kiro Task <-- use -- Claude Code
          <-- use -- Gemini CLI
です。
この二つの情報を参考に、表示を綺麗にしたDrawioのファイルを生成してください。
ファイルの拡張子は.drawioにしてください。


良さそうです。
ちょっと手間ですが、手書き画像だけでなく、
図の説明も入れるとスムーズに図の生成ができそうですね。


おわり

おわりです!!

GitHub CLIで複数のGitHubアカウントを切り替える

個人用と仕事用、どちらの鍵を設定すれば良いか問題

複数のGitHubアカウントを利用する場合、GitHubへのアクセスにSSHを利用すると、面倒な時がある。

SSHへの接続には、.ssh/configに定義された鍵が使われるが、 例えば、個人用アカウントと仕事用アカウントを併用しているような場合、.ssh/configの設定でどのように設定すればいいか困ることになる。

「個人用と仕事用、どちらの鍵を設定すれば良いか」問題です。
"Host github-work"とか、別の名前を定義する方法もありますけど。

Host github.com
    HostName github.com
    User git
    Port 22
    IdentityFile ~/.ssh/id_ed25519.home # <--- 個人用と仕事用、どちらの鍵を設定すれば良い?

ではどうするか?こうするべし

  • GitへはHTTPSで接続する。
  • パーソナルアクセストークンを認証に利用する。
  • GitHub CLI(gh)でパーソナルアクセストークンを管理する。
  • 複数のGitHubのアカウントの切替は、gh auth switchコマンドで行う。
GitHub CLIでアカウントの管理 + GitHub HTTPS接続 + パーソナルアクセストークン利用

たぶんこれが一番楽だと思います。


セットアップ手順

  • GitHub CLI(gh)を導入する。
  • GitHubへのアクセスはHTTPS接続を選択し、パーソナルアクセストークンで認証する。


1. GitHub CLI(gh)の導入

Macの場合

brew install gh

Ubuntuの場合

(type -p wget >/dev/null || (sudo apt update && sudo apt-get install wget -y)) \
    && sudo mkdir -p -m 755 /etc/apt/keyrings \
        && out=$(mktemp) && wget -nv -O$out https://cli.github.com/packages/githubcli-archive-keyring.gpg \
        && cat $out | sudo tee /etc/apt/keyrings/githubcli-archive-keyring.gpg > /dev/null \
    && sudo chmod go+r /etc/apt/keyrings/githubcli-archive-keyring.gpg \
    && sudo mkdir -p -m 755 /etc/apt/sources.list.d \
    && echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" | sudo tee /etc/apt/sources.list.d/github-cli.list > /dev/null \
    && sudo apt update \
    && sudo apt install gh -y
sudo apt update
sudo apt install gh



2. GitHub CLI(gh)の設定

gh auth loginコマンドで、アカウントのパーソナルアクセストークンを取得します。
Gitの操作で使うプロトコルHTTPSを選択します。
作成したパーソナルアクセストークンはghで管理されます。

gh auth login
? Where do you use GitHub?
-> GitHub.com # もしくはGitを管理するサービスのドメイン

? What is your preferred protocol for Git operations on this host?
-> HTTPS

? Authenticate Git with your GitHub credentials?
->  Yes

? How would you like to authenticate GitHub CLI?
-> Login with a web browser      # Webブラウザを使える環境ならこちらを選択
-> Paste an authentication token # リモートのサーバ環境とかなら、こちらを選択


複数のGitHubアカウントがあるので、利用するアカウントの数だけ、git auth loginコマンドで認証を行います。
ひととおりアカウントを設定したら、git auth setup-gitコマンドで、認証をgh経由で行うように設定します。

gh auth setup-git



利用手順

Gitの操作

GitHubのレポジトリをcloneする時は、HTTPSのURLでcloenするか、ghコマンドを使います。
GitHubとの接続には、ghの管理するパーソナルアクセストークンが使われます。

git clone https://github.com/foo/var

# or

gh repo clone foo/var



GitHubに接続するアカウントを切り替える

GitHubに接続するアカウントを切り替える際は、gh auth switchコマンドを使用します。

git auth switch


が、しかし、Git接続時に使われるuser.emailuser.namegit auth switchでは変更されません。
これは別でgit configで設定することになります。

git config --global user.name "taku-o"
git config --global user.email "mail@nanasi.jp"



アカウント切り替えスクリプト例 (~/bin/git-switch-account)

アカウント切替については、おそらく何度も実行することになるので、スクリプトにまとめておくと良いでしょう。

#!/bin/bash

# 引数が指定されているか確認
if [ -z "$1" ]; then
  echo "使用法: $0 <user>"
  echo "利用可能なアカウント: taku-o, user1"
  echo "事前にgh auth loginしてください"
  echo "gh auth login --hostname github.com"
  exit 1
fi

COMMAND="$1" # 最初の引数をCOMMAND変数に格納

case "$COMMAND" in
  "taku-o")
    echo "Gitアカウントをgithub.com mail@nanasi.jpに切り替えます..."
    git config --global user.name "taku-o"
    git config --global user.email "mail@nanasi.jp"
    gh auth switch --user taku-o --hostname github.com
    ;;
  "user1")
    echo "Gitアカウントをgithub.com user1@example.comに切り替えます..."
    git config --global user.name "user1"
    git config --global user.email "user1@example.com"
    gh auth switch --user user1 --hostname github.com
    ;;
  *) # 上記のどれにも一致しない場合
    echo "無効なアカウント: $COMMAND"
    echo "利用可能なアカウント: taku-o, user1"
    exit 1
    ;;
esac

exit



HTTPS接続でプライベートレポジトリのgit cloneが出来ない!! (Mac環境)

HTTPS接続でprivateなレポジトリをgit cloneしようとした時、レポジトリがnot foundエラーになってしまった。原因はなに?
この問題は主に複数のGitHubアカウントを利用していると発生する。

git clone https://github.com/foo/var
Cloning into 'var'...
remote: Repository not found.
fatal: repository 'https://github.com/foo/var.git/' not found

原因はなに?

検索すると、GitHubHTTPS接続できないときは、SSH接続を使いなさいという解決策を何度か見かけましたが、自分の環境でこの問題を解決してみました。
Mac環境です。


原因ケース1: gh利用時。想定しているアカウントがアクティブになっていない

ghを利用してGitHubアカウントを切り替えているが、接続したいアカウントがghのアクティブアカウントになっていないケース。
gh auth statusでアクティブアカウントを確認します。

gh auth status
github.com
  ✓ Logged in to github.com account taku-o (keyring)
  - Active account: false
  - Git operations protocol: https
  - Token: gho_************************************
  - Token scopes: 'gist', 'read:org', 'repo', 'workflow'

  ✓ Logged in to github.com account foo (keyring)
  - Active account: true # ←←←←←←← 想定外のアカウントがactive
  - Git operations protocol: https
  - Token: gho_************************************
  - Token scopes: 'gist', 'read:org', 'repo', 'workflow'

想定したアカウントがアクティブになっていない場合は、gh auth switchでアカウントをアクティブにしましょう。

gh auth switch

原因ケース2: キーチェーンアクセスにGitHubに接続するアカウント名が設定されている

まずユーザー名を指定して、git cloneできるか確認します。

git clone https://github.com/foo/var

# ↓ このようにユーザー名を指定

git clone https://taku-o@github.com/foo/var

もし、ユーザー名を指定したgit cloneが成功するなら、GitHubに接続する際、GitHubに渡されているアカウント名が間違っているということです。
次のコマンドで、GitHubに接続する際の認証に何が使われているか確認します。

git config --show-origin --get-all credential.helper
file:/Applications/Xcode.app/Contents/Developer/usr/share/git-core/gitconfig osxkeychain
file:/Users/taku-o/.gitconfig gh

osxkeychainが指定されているなら、キーチェーンアクセスにGitHub接続用の情報が作られているかもしれません。
キーチェーンアクセスアプリを起動して、github.comを検索します。

github.com
種類:インターネットパスワード
アカウント:foo
場所 https://github.com

もし、キーチェーンアクセスに登録がある場合、ghで指定したアクティブアカウントではなく、キーチェーンアクセスに設定されているアカウントで接続を試みるようなのです。
結果、プライベートなレポジトリにアクセスできないエラーが発生することになります。

  • キーチェーンアクセスから消して作り直す
  • キーチェーンアクセスから消して、ghベースでの管理に移行。

などで対応しましょう。


原因ケース3: .netrcに接続情報が登録されている

~/.netrcgithub.comへの接続情報が登録されているケース。そのため、git cloneした際に、.netrcに登録されているGitHubアカウントで接続されてしまっていた。

# ~/.netrc
machine github.com
  login foo
  password gxxxx

~/.netrcは同一ドメインで、複数アカウントを利用することは考慮されていません。
~/.netrcに定義されている、github.comへの接続情報は消してしまって、gh管理に移行するのが良いと思います。

Cursorでcontainer-useを使う

container-use

https://github.com/dagger/container-use

Container Use を利用すると、各コーディングエージェントがそれぞれ独自のコンテナ化された環境を持てます。これにより、1つのエージェントにつきっきりになる状態から、複数のエージェントがあなたの好むスタックで安全かつ独立して作業できるようになります。 (翻訳まんま)

AIが生成した処理結果はGitブランチを通じてやりとりします。 DockerとGitが入っていることが前提のツール。

Google Julesとか最近のAIのコード生成ツールは、最初にGitのbranchを作って、そこで作業するようになっているので、container-useを使うと、そのお作法に似たことができるわけですね。


1. セットアップ手順

1-1. container-use コマンドのインストール

curl -fsSL https://raw.githubusercontent.com/dagger/container-use/main/install.sh | bash

デフォルトでは ~/.local/bin/cu にインストールされます。
Macの場合、/usr/bin/cu が入っているので、どこかPATHが通らない場所に移動しても良いと思います。 コマンド名が被っているのは嫌ですよね。
名前を変えたい、というissueも無くはないですね。closeされてましたけど。

mkdir -p ~/.cursor/local/bin
mv ~/.local/bin/cu ~/.cursor/local/bin
rm -rf ~/.local/bin

1-2. MCP設定

CursorのMCP設定ファイル(mcp.json)に以下を追加します。 これは設定例なので、cuコマンドのPATHは適当に修正してください。

{
  "mcpServers": {
    "container-use": {
      "command": "/Users/taku-o/.cursor/local/bin/cu",
      "args": ["stdio"]
    }
  }
}

設定後、Cursorを再起動し、container-useのMCPが読み込まれているか確認しておきましょう。

1-3. ルールファイルの生成

プロジェクトのルートディレクトリで、container-use用のルールファイルを生成します。

curl --create-dirs -o .cursor/rules/container-use.mdc \
  https://raw.githubusercontent.com/dagger/container-use/main/rules/cursor.mdc

毎回手動で実行するのが面倒になら、スクリプト化しておくと良いと思います。

cat > ~/bin/cu-rule-generate <<'EOF'
curl --create-dirs -o .cursor/rules/container-use.mdc \
  https://raw.githubusercontent.com/dagger/container-use/main/rules/cursor.mdc
EOF
chmod +x ~/bin/cu-rule-generate

2. container-use を使ってみる

2-1. プロジェクトの準備

container-useはGitを利用して動作するので、 操作対象のプロジェクトがGitで管理されている状態でないといけません。
最初にプロジェクトをgit init、git commitまでしておきます。

mkdir hello_world
cd hello_world
git init
echo "Hello World" > README.md
git add .
git commit -m "initial upload"

2-2. ルールファイルの用意

Cursorを開き、ルールファイルを作成します。

curl --create-dirs -o .cursor/rules/container-use.mdc \
  https://raw.githubusercontent.com/dagger/container-use/main/rules/cursor.mdc

2-3. コード生成の依頼

Cursorには複数Workspaceを利用して開発する機能がありますが、自分はあまり信用していません。
CursorのAIが生成したファイルを変な場所に出力してしまう。よくありますよね。
プロジェクトはworkspaceルートにある方が良いですね。

ターミナルで"cursor ."と実行すると、カレントディレクトリをworkspaceルートにしてCursorが立ち上がります。 このテク、最近6/6にあった、Cursor Meetup Tokyoで知りました。

cursor .

Cursorを開いたら、AIにコードを生成して貰います。
例:

作るコードは
Go製で
コマンドを実行するとhello worldと表示する
CLIアプリを作って欲しい。
できるだけ簡単な作りで。

出来た!
(スクリーンショット取り忘れただけだから、詳細少し違うのは気にしてはいけない)

git branchが作成されて、そこにコードが作成されます。

この結果が気に入らない場合は、追加でAIとお話しして直して貰いましょう。
終わったら、branchをマージするなら、GitHubにpushして、Pull Requestを作成するなりすることになります。


3. 気づいたこと

3-1. container-useが使われないことがある

container-useが使われずに、ローカルにもファイルを作られてしまう時があります。
AIにMCPのcontainer-use使ってください、と言えば良いのだろうか?

駄目でした。

cursorコマンドで立ち上げたから、ルールファイルをまだ読んでいないのが原因でしょうか。 @Fileでcontainer-use.mdcを読ませてしまうのが良いかもです?

3-2. container-useが作ったdockerのcontainerが残っている

container-useが作業時にDockerのコンテナを作るのですが、 "docker ps"コマンドで確認すると、 それが作業終了後にも残っています。 作成したコードに対して、まだまだ追加で修正をしてもらう可能性があるので、作業終了後に即コンテナを消されても困ります。なので、わからなくもない挙動ではあります。

docker ps

一通りの作業が終わったら、"docker stop"をして、コンテナを停止するのが良いと思います。

docker stop <container_id>
docker stop 14cbc892ea42

3-3. container作成に失敗することがある。

container-useがコンテナを作る際、

Missing required parameter 'secrets' for tool environment_update

とメッセージが出て、コンテナ作成に失敗することがあります。原因不明。
しばらく後に試したら問題なくなりました。

これが発生すると、その時点で作業を中止してくれずに、 そのまま作業を進めてコードをファイルシステムに出力して、環境を汚してします。
アー困ります困ります。 なにか工夫が要るかもしれない。