stenyan[.]dev

JAEN

I made a tool "ayumi", for appending raw LLM instructions to commit messages

As more people write code with coding agents, I have started to care more about what specific instructions led to that given diff. So I made a tool that includes the raw instructions sent to LLMs directly in commit messages.

How it works

The idea is to use Claude Code or Codex's UserPromptSubmit hook1 together with Git's prepare-commit-msg hook2.

UserPromptSubmit fires when a prompt is submitted to a coding agent. At that point, ayumi looks at the current repository and branch, and saves the prompt content to a file for that repository/branch pair.

Shell
[User instruction]
      |
      v
[Claude Code / Codex]
      |
      | UserPromptSubmit Hook fires
      v
[ayumi]
      |
      | Append to a file for the Repository + Branch pair
      v
[File containing recorded instructions]
Example: ~/.local/share/ayumi/.../foo.jsonl

Later, when creating a commit, ayumi is triggered again through Git's prepare-commit-msg hook. This hook fires when Git prepares the commit message, so it runs regardless of whether the commit is created by a human or by a coding agent. ayumi again uses the current repository and branch pair, reads the instructions recorded so far, and appends them to the commit message.

Shell
[git commit]
      |
      | prepare-commit-msg Hook fires
      v
[ayumi]
      |
      | Read the file for the Repository + Branch pair
      v
[File containing recorded instructions]
      |
      | Retrieve instructions
      v
[Commit message]
      |
      | Append instructions
      v
[Final commit message]

Thoughts

I have previously tried doing something similar by having an Agent Skill to generate commit messages, but skills can be inconsistent about when they trigger. That led me to try using hooks this time.

I chose Go because supply chain attacks have become a real concern lately, and I wanted something that could mostly work with only the standard library.

Aside: Commit message format

Deciding what format to use when appending instructions to the commit message turned out to be a surprisingly important detail. At first, I implemented it as a list like this:

Shell
feat: add an amazing feature

AI Instructions:
- instruction 1
- instruction 2
- instruction 3

But with that format, if a single instruction spans multiple lines, it becomes hard to tell where one instruction starts and ends.

Shell
feat: add an even more amazing feature

AI Instructions:
- I have an idea like the following, please build it
- hoge
- fuga
- poyo (end of instruction 1)
- (start of instruction 2) Looks good. Next, please change this part like this

So I settled on a quote-style format where each instruction is separated by a blank line.

Shell
feat: add an even more amazing feature

AI Instructions:
> I have an idea like the following, please build it
- hoge
- fuga
- poyo

> Looks good. Next, please change this part like this

Footnotes

  1. Documentation for the UserPromptSubmit hook: https://code.claude.com/docs/en/hooks#userpromptsubmit, https://developers.openai.com/codex/hooks#userpromptsubmit

  2. Documentation for the prepare-commit-msg hook: https://git-scm.com/docs/githooks#_prepare_commit_msg