Skip to main content

Agent Diary

Remember what you did with an AI. Automatically when a Claude Code session ends, or on one command in Codex, Agent Diary records what you asked for and what changed.

CI License: MIT Python 3.8+ Core Dependencies: 0

English | 한국어

This is a community project. It is not an official Anthropic or OpenAI project.

Agent Diary demo

1. Why

Work done with an AI lives in a chat window, and chat windows close. Two days later there is no way back to why a file was changed the way it was, and when a weekly review or a status report comes due you are working from memory. A commit log keeps the result; it does not keep what you asked for or what was tried on the way there.

Agent Diary captures that context at the moment a session ends. There is no habit to build.

One finished session appends an entry like this.

### ⏰ 14:30:15 | 📁 `my-app`

**🏷️ Categories:** `feature` `test`

**📋 Task Requests:**
  1. Add JWT authentication to login
  2. Write the tests as well

**📄 Files Created:**
  - `src/auth/jwt_handler.py`
  - `tests/test_auth.py`

**✏️ Files Modified:**
  - `src/api/routes.py`

**🔀 Git:**
  - 🌿 Branch: `feat/jwt-auth`
  - Commit: `a1b2c3d` feat: verify tokens and cover login

**📊 Code Stats:** +145 / -12 lines (5 files)

**⚡ Key Commands:**
  - `export API_KEY=****`
  - `pytest -q`

**📝 Work Summary:**
  - Added JWT verification middleware and covered the login failure path

**🔒 1 secrets masked**

Categories are inferred from the work. Branch, commits and diff stats are read from the repository. Anything that looks like a secret — the API_KEY above — is masked before the file is written.

What makes it different

  • It is automatic. In Claude Code a Stop Hook picks up the end of a session. You never have to decide to record something.
  • Zero core dependencies. Standard library only. requests is added only if you use the Notion integration.
  • Local files. Plain Markdown, so it greps, it opens in Obsidian, and it outlives any service.
  • It scales to a team. Push to a Notion work-log database when you need to, or export to Slack, Discord and GitHub.
pip install agent-diary
agent-diary init

Nothing else is required. Every Claude Code session from then on lands in ~/working-diary/YYYY-MM-DD.md.

This project was claude-diary, then working-diary, and is now agent-diary. If you installed it under an older name, the working-diary and claude-diary commands still work.

The internal Python package is still claude_diary. install writes python -m claude_diary.hook into the user's settings.json, so renaming it would stop an existing Stop Hook silently. A distribution name that differs from the import name is ordinary in Python.

Supported Agents

Agent Auto diary Manual Markdown Notion work log Apply/refresh
Claude Code Stop Hook /diary /diary-notion agent-diary install --force
Codex None $diary $diary-notion agent-diary install --force --codex-only

Package installation is shared, but agent setup is different. Use --codex-only for Codex-only setup without modifying Claude Code settings. --codex remains as a compatibility option that also refreshes the Claude Code hook and slash commands.

Storage Paths

Automatic diaries are appended to daily files.

~/working-diary/
  2026-03-15.md
  2026-03-16.md
  .session_counts.json
  weekly/
    W11_2026-03-09.md

Manual diaries are stored separately by date and project.

~/working-diary/manual/
  2026-04-29/
    my-project/
      2026-04-29.md

2. Usage

Follow the sequence for the target workflow.

Goal Command sequence
Claude Code Markdown auto/manual diary pip install agent-diary -> agent-diary init -> agent-diary install --force
Claude Code with Notion work log pip install "agent-diary[notion]" -> agent-diary init -> agent-diary install --force -> agent-diary diary-notion init -> agent-diary diary-notion ensure
Codex Markdown manual diary pip install agent-diary -> agent-diary init --codex-only -> agent-diary install --force --codex-only -> open a new Codex session
Codex with Notion work log pip install "agent-diary[notion]" -> agent-diary init --codex-only -> agent-diary install --force --codex-only -> agent-diary diary-notion init -> agent-diary diary-notion ensure -> open a new Codex session

2-1. Package Install And Basic Setup

pip install:

pip install agent-diary
agent-diary init

With Notion support:

pip install "agent-diary[notion]"
agent-diary init

Claude Code plugin installation is a separate distribution path for Claude Code plugin marketplace users.

# Run inside Claude Code
/plugin marketplace add https://github.com/solzip/agent-diary
/plugin install working-diary

The plugin distributes Claude Code hook settings. The working-diary CLI comes from the Python package, so Python package installation and agent-diary init are still required.

Install from source:

git clone https://github.com/solzip/agent-diary.git
cd working-diary
pip install -e .
agent-diary init

Install from source with Notion support:

pip install -e ".[notion]"

agent-diary init creates the config file and diary directory, and it also registers the Claude Code Stop Hook. If you only use Codex, run agent-diary init --codex-only to avoid modifying Claude Code settings.

Run the agent-specific apply command below to refresh Claude Code slash commands or Codex skills.

2-2. Claude Code Usage

Claude Code supports automatic diaries when sessions end and manual diaries during a session.

Apply or refresh Claude Code setup:

agent-diary install --force

Automatic diary flow:

Claude Code session ends
  -> Stop Hook runs
  -> transcript is parsed
  -> ~/working-diary/YYYY-MM-DD.md

Manual Markdown diary:

/diary

Notion work log:

/diary-notion

/diary finds the Claude Code transcript for the current project and records it through the agent-diary write core. /diary-notion creates task-row JSON from the session and passes it to agent-diary diary-notion push.

2-3. Codex Usage

Codex does not use an automatic hook. It records only when the user invokes a skill.

Apply or refresh Codex setup:

agent-diary install --force --codex-only

--codex-only installs only the Codex skills under ~/.codex/skills and does not modify Claude Code hooks or slash commands. --codex remains as a compatibility option that also refreshes the Claude Code setup.

Manual Markdown diary:

$diary

Notion work log:

$diary-notion

$diary and $diary-notion create JSON from the current Codex conversation and tool activity, then call the same core CLI. Already-running Codex sessions keep the skills loaded at startup. Refreshed skills are applied in a new Codex session.

2-4. First Notion Setup

Notion work logs require the optional requests dependency.

pip install "agent-diary[notion]"

For source installs:

pip install -e ".[notion]"

Setup steps:

  1. Create a Notion integration at https://www.notion.so/my-integrations and copy the token.
  2. Create a Notion root page, for example Agent Diary.
  3. Share the root page with the integration.
  4. Save the configuration.
agent-diary diary-notion init

diary-notion init stores the Notion token and root page ID you enter in local config. If you later set CLAUDE_DIARY_NOTION_TOKEN or CLAUDE_DIARY_NOTION_ROOT_PAGE_ID, those environment variables override the saved config values.

  1. Ensure the yearly Entries database, schema, and views.
agent-diary diary-notion ensure
  1. Run /diary-notion or $diary-notion from an agent session.

2-5. Notion Push Behavior

agent-diary diary-notion push --input .diary-notion-<id>.json
agent-diary diary-notion push --input .diary-notion-<id>.json --force
agent-diary diary-notion push --input .diary-notion-<id>.json --dry-run
  • Default push skips rows already recorded with the same Session ID + Task Index.
  • --force archives prior rows for the session and pushes again.
  • --dry-run prints the rows and page bodies that would be created without writing to Notion. Add --preview-file <path> to save the same rendering as Markdown.
  • If a Task Group already has recorded sessions, the title gets an (N차) ordinal. The first session of a group is left alone.
  • If any task fails, the command exits with code 1 and preserves the input JSON.
  • Fully successful pushes and already-skipped pushes exit with code 0.

2-6. What A Push Leaves On Disk (Run Artifacts)

Every push writes a record of the run under the current working directory, by default. --dry-run writes it too.

<cwd>/.codefleet/runs/<YYYYMMDD-HHMMSS-session>/
  input.json        the original task JSON
  git-diff.patch    the working tree diff at push time
  preview.md        the rendered Notion body
  manifest.json     the files above with sha256, plus a push result summary

Notion is the destination, not the record. If a push half-fails, or a row is later edited by hand, this local copy is the only way back to what was actually submitted.

git-diff.patch contains your uncommitted code. Keep it out of your repository:

.codefleet/runs/

To relocate or disable it:

agent-diary diary-notion push --input <json> --artifact-dir build/diary-runs
agent-diary diary-notion push --input <json> --no-artifacts

2-7. Review Queue

Review is a judgement a person makes after the fact, so no stage of the recording pipeline declares work reviewed on its own. Push files every new row as Needs Review, and only this command's --apply promotes a row to Reviewed.

agent-diary diary-notion review              # list rows awaiting review (read-only)
agent-diary diary-notion review --apply      # set Reviewed + Last Reviewed=today
agent-diary diary-notion review --year 2026

Without --apply nothing is written, matching the ensure --dry-run / ensure pattern.

2-8. Notion Sub-Items

Expandable task hierarchy uses Notion native Sub-items. Enable it once in the Notion UI.

  1. Open the yearly Entries database.
  2. Open the top-right ... menu and enable Sub-items.
  3. Run agent-diary diary-notion ensure again.

Rows are still recorded if Sub-items are not enabled. Only visual nesting is missing, and push prints a hint.

3. Logic

3-1. Core Logic

The core handles actual recording independently of the agent.

input
  -> transcript or agent-authored JSON
  -> cwd, session_id, task metadata

core processing
  -> parser
  -> Git enrichment
  -> category inference
  -> secret scan
  -> formatter
  -> writer or Notion exporter
  -> audit/index/export retry

Key modules:

Area File Role
CLI entry src/claude_diary/cli/__init__.py Routes the agent-diary command and its working-diary / claude-diary aliases
Automatic diary core src/claude_diary/core.py Claude Code Stop Hook diary pipeline
Manual diary core src/claude_diary/cli/write.py Handles /diary, $diary, and agent-diary write
Notion push src/claude_diary/cli/notion_push/ Pushes task JSON as Notion rows (split into validate/properties/relations/artifacts)
Notion schema/view src/claude_diary/cli/notion_ensure.py Ensures schema v8, 5 core views and 5 operating views
Notion review queue src/claude_diary/cli/notion_review.py Lists Needs Review rows; --apply records Reviewed
Formatter src/claude_diary/formatter.py Creates Markdown entries and Notion page bodies

3-2. Claude Code Logic

Automatic diary:

Claude Code Stop Hook
  -> src/claude_diary/hook.py
  -> core.process_session(session_id, transcript_path, cwd)
  -> ~/working-diary/YYYY-MM-DD.md

Manual diary:

/diary
  -> agent-diary write
  -> find Claude transcript for the current cwd
  -> append to manual diary path

/diary-notion
  -> agent creates task JSON
  -> agent-diary diary-notion push --input <json>
  -> push rows to Notion Entries DB

agent-diary install --force refreshes:

  • ~/.claude/settings.json Stop Hook
  • ~/.claude/commands/diary.md
  • ~/.claude/commands/diary-notion.md

3-3. Codex Logic

Codex has no Stop Hook. Global skills call the core CLI.

$diary
  -> Codex writes current session content to .diary-<id>.json
  -> agent-diary write --input .diary-<id>.json
  -> append to manual diary path

$diary-notion
  -> Codex splits the session into tasks
  -> writes .diary-notion-<id>.json
  -> agent-diary diary-notion push --input .diary-notion-<id>.json
  -> push rows to Notion Entries DB

agent-diary install --force --codex-only refreshes:

  • ~/.codex/skills/diary/SKILL.md
  • ~/.codex/skills/diary-notion/SKILL.md

4. CLI

Core commands:

agent-diary init
agent-diary init --codex-only
agent-diary install --force
agent-diary install --force --codex
agent-diary install --force --codex-only
agent-diary uninstall
agent-diary uninstall --codex
agent-diary uninstall --codex-only

agent-diary write
agent-diary write --input .diary-<id>.json

agent-diary diary-notion init
agent-diary diary-notion ensure
agent-diary diary-notion ensure --dry-run
agent-diary diary-notion ensure --year 2026

agent-diary diary-notion push --input .diary-notion-<id>.json
agent-diary diary-notion push --input .diary-notion-<id>.json --force
agent-diary diary-notion push --input .diary-notion-<id>.json --dry-run
agent-diary diary-notion push --input .diary-notion-<id>.json --preview-file preview.md
agent-diary diary-notion push --input .diary-notion-<id>.json --artifact-dir build/diary-runs
agent-diary diary-notion push --input .diary-notion-<id>.json --no-artifacts

agent-diary diary-notion ops
agent-diary diary-notion ops --stale-days 14
agent-diary diary-notion ops --json

agent-diary diary-notion review
agent-diary diary-notion review --apply

agent-diary notion push --input .diary-notion-<id>.json

Search and maintenance commands:

agent-diary search "keyword"
agent-diary filter --project my-app
agent-diary trace src/main.py
agent-diary stats
agent-diary weekly
agent-diary audit
agent-diary audit --verify
agent-diary config
agent-diary config --set lang=en
agent-diary migrate
agent-diary reindex
agent-diary delete --last

Extension commands:

agent-diary config --add-exporter slack
agent-diary config --add-exporter discord
agent-diary config --add-exporter obsidian
agent-diary config --add-exporter github
agent-diary dashboard
agent-diary dashboard --serve --port 8787
agent-diary team stats
agent-diary team weekly
agent-diary team monthly --month 2026-06
agent-diary team init --repo <url> --name <name>
agent-diary team add-member --name <name> --role member

The legacy CLI remains supported.

agent-diary write
agent-diary diary-notion ensure

5. Configuration

The config file is stored at the OS-specific user config path under claude-diary/config.json. If you configure exporters such as Notion, Slack, or Discord, API tokens, webhook URLs, and root page IDs are stored in this local config. CLI output masks long token and webhook values.

Environment variable Description Default
CLAUDE_DIARY_LANG Diary language, ko or en ko
CLAUDE_DIARY_DIR Automatic diary path ~/working-diary
CLAUDE_DIARY_MANUAL_DIR Manual diary path ~/working-diary/manual
CLAUDE_DIARY_TZ_OFFSET UTC offset 9
CLAUDE_DIARY_NOTION_TOKEN Notion token, overrides config -
CLAUDE_DIARY_NOTION_ROOT_PAGE_ID Notion root page ID, overrides config -
CLAUDE_DIARY_SKIP 1, true, or yes skips Claude Code Stop Hook auto diary -

If PowerShell output shows broken Korean or emoji characters, switch the current session output encoding to UTF-8.

[Console]::OutputEncoding = [System.Text.UTF8Encoding]::new()
$OutputEncoding = [System.Text.UTF8Encoding]::new()

6. Features

  • Automatic category inference
  • Git branch, commit, and diff stat recording
  • Secret scanning and masking
  • Search index
  • Notion work log: agent-diary diary-notion init -> agent-diary diary-notion ensure
  • Notion operations report: agent-diary diary-notion ops for blocked/review/next action/stale/work days/today-plan candidates/parent status signals
  • Review queue: agent-diary diary-notion review. Push always files as Needs Review; only --apply promotes a row to Reviewed
  • Run artifacts: every push preserves input.json, git-diff.patch, preview.md and manifest.json locally, each sha256-stamped
  • Automatic (N차) ordinals for sessions continuing the same Task Group, with no extra column
  • A day's rows read in the order the work was done (Date ties broken by Task Index)
  • Slack, Discord, Obsidian, GitHub exporters: agent-diary config --add-exporter <name>
  • HTML dashboard: agent-diary dashboard or agent-diary dashboard --serve --port 8787
  • Audit log and source checksum verification
  • Team mode: agent-diary team init --repo <url> --name <name>

7. Troubleshooting

Symptom Check
/diary or /diary-notion does not use the latest instructions Run agent-diary install --force to refresh the hook and slash commands
$diary or $diary-notion does not use the latest instructions Run agent-diary install --force --codex-only, then open a new Codex session
Notion push reports an auth error Check the integration token, root page ID, and page sharing
Notion task hierarchy is not nested Enable Sub-items once in the Notion Entries database UI
Re-push might duplicate rows Default push skips the same Session ID + Task Index; use --force to rewrite
A .codefleet/ directory appeared in my project That is the push run record. Add .codefleet/runs/ to .gitignore, or disable it with --no-artifacts (see 2-6)
I want to drop the (N차) suffix from titles It counts prior sessions of the same Task Group. Leave task_group empty and no suffix is added
PowerShell text is garbled Apply the UTF-8 output setting above

8. Development

pip install -e ".[dev,notion]"
python -m pytest -q
python -m ruff check .

9. Roadmap

This README focuses on currently usable functionality. Detailed design and planning artifacts live under docs/.

Area Status
Available Claude Code Stop Hook, Codex skills, Markdown diaries, Notion task row push, schema v8 / view ensure, ops operations report, review queue, push run artifacts
In progress Notion schema reduction (#12), dry-run ordinals (#10), Schema Version string fix (#11)
Next Windows install/output experience, Notion sub-item guidance
Under review SQLite search index, Cursor/Windsurf/VS Code integration

10. Documentation

11. License

MIT

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

agent_diary-4.3.1.tar.gz (195.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

agent_diary-4.3.1-py3-none-any.whl (126.3 kB view details)

Uploaded Python 3

File details

Details for the file agent_diary-4.3.1.tar.gz.

File metadata

  • Download URL: agent_diary-4.3.1.tar.gz
  • Upload date:
  • Size: 195.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for agent_diary-4.3.1.tar.gz
Algorithm Hash digest
SHA256 02e8f9f30d196a0dd2e7e27221c1d75fb71976e0a9e5dc16f8c311e0a09f798b
MD5 fd3aaa7452612a7369533a167144204c
BLAKE2b-256 b3118236df55c9a656e6b6a6be3e99a355cb49bab1b20a00bd3ee0b282b44af6

See more details on using hashes here.

Provenance

The following attestation bundles were made for agent_diary-4.3.1.tar.gz:

Publisher: release.yml on solzip/agent-diary

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file agent_diary-4.3.1-py3-none-any.whl.

File metadata

  • Download URL: agent_diary-4.3.1-py3-none-any.whl
  • Upload date:
  • Size: 126.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for agent_diary-4.3.1-py3-none-any.whl
Algorithm Hash digest
SHA256 51d8488e1f1d2e1ab831a556ee8e8f8710506fd9870cffd6f0a78997ffbce5ad
MD5 0ee7b5eef84425aaa078683944506b99
BLAKE2b-256 88e9019336d19202384cbaf5fff42056da213cd71b862e4fd4f2ba48a43fe033

See more details on using hashes here.

Provenance

The following attestation bundles were made for agent_diary-4.3.1-py3-none-any.whl:

Publisher: release.yml on solzip/agent-diary

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page