Clu CLI
Architecture
The CLI now follows a layered layout:
src/clu/cli/contains Click command adapters only.src/clu/lib/contains feature orchestration and command entrypoints.src/clu/models/contains flat Pydantic models and enums.src/clu/utils/contains shared pure helpers.src/clu/api/contains backend auth and sync clients.src/clu/store/contains SQLite repositories and the store facade.src/clu/adapter/,src/clu/git.py, andsrc/clu/transcript.pyremain infrastructure-facing modules used by the library layer.
Commands
clu authclu install --global(default is in the current directory)clu append --agent codex/claude/geminiclu flush
Config path: $HOME/.clu/config.toml -- use this to store any secrets, preferences etc.
Happy Path Flow
- User does
clu auth login-- this opens a web based oauth login- After login, the CLI should silently refresh expired access tokens using the stored refresh token.
- User does
clu auth statusto verify the current session and test refresh behavior. - User does
clu installin the project directory, orclu install --globalif they want to install it in the gobal config.- This asks the user what agent to install it for (TUI style picker)
- Installing for claude code modifies the
.claude/settings.jsonand installs theclu appendcommand as the hook for all events and all matches (an example for the settings is added below) - Hooks Reference for Claude: https://code.claude.com/docs/en/hooks#hook-events
- Installing for claude code modifies the
- This asks the user what agent to install it for (TUI style picker)
- The
clu appendcommand reads the hook payload from stdin, stores the raw event locally, and incrementally parses transcript messages into SQLite. - The
clu flushcommand syncs dirty sessions to/sessionsand then bulk-uploads dirty messages to/session-messagesin batches.
Eventual Direction
This SQLite file is the local capture layer. The backend correlates the synced session and message data with GitHub PR events later; the CLI no longer builds or submits a final changeset payload itself.
Settings JSON
{
"hooks": {
"SessionStart": [
{
"matcher": "",
"hooks": [
{
"type": "command",
"command": "/Users/junaidrahim/Code/sandbox/log-hook.sh"
}
]
}
],
"UserPromptSubmit": [
{
"matcher": "",
"hooks": [
{
"type": "command",
"command": "/Users/junaidrahim/Code/sandbox/log-hook.sh"
}
]
}
],
"PreToolUse": [
{
"matcher": "",
"hooks": [
{
"type": "command",
"command": "/Users/junaidrahim/Code/sandbox/log-hook.sh"
}
]
}
],
"PermissionRequest": [
{
"matcher": "",
"hooks": [
{
"type": "command",
"command": "/Users/junaidrahim/Code/sandbox/log-hook.sh"
}
]
}
],
"PermissionDenied": [
{
"matcher": "",
"hooks": [
{
"type": "command",
"command": "/Users/junaidrahim/Code/sandbox/log-hook.sh"
}
]
}
],
"PostToolUse": [
{
"matcher": "",
"hooks": [
{
"type": "command",
"command": "/Users/junaidrahim/Code/sandbox/log-hook.sh"
}
]
}
],
"PostToolUseFailure": [
{
"matcher": "",
"hooks": [
{
"type": "command",
"command": "/Users/junaidrahim/Code/sandbox/log-hook.sh"
}
]
}
],
"Notification": [
{
"matcher": "",
"hooks": [
{
"type": "command",
"command": "/Users/junaidrahim/Code/sandbox/log-hook.sh"
}
]
}
],
"SubagentStart": [
{
"matcher": "",
"hooks": [
{
"type": "command",
"command": "/Users/junaidrahim/Code/sandbox/log-hook.sh"
}
]
}
],
"SubagentStop": [
{
"matcher": "",
"hooks": [
{
"type": "command",
"command": "/Users/junaidrahim/Code/sandbox/log-hook.sh"
}
]
}
],
"TaskCreated": [
{
"matcher": "",
"hooks": [
{
"type": "command",
"command": "/Users/junaidrahim/Code/sandbox/log-hook.sh"
}
]
}
],
"TaskCompleted": [
{
"matcher": "",
"hooks": [
{
"type": "command",
"command": "/Users/junaidrahim/Code/sandbox/log-hook.sh"
}
]
}
],
"Stop": [
{
"matcher": "",
"hooks": [
{
"type": "command",
"command": "/Users/junaidrahim/Code/sandbox/log-hook.sh"
}
]
}
],
"StopFailure": [
{
"matcher": "",
"hooks": [
{
"type": "command",
"command": "/Users/junaidrahim/Code/sandbox/log-hook.sh"
}
]
}
],
"TeammateIdle": [
{
"matcher": "",
"hooks": [
{
"type": "command",
"command": "/Users/junaidrahim/Code/sandbox/log-hook.sh"
}
]
}
],
"InstructionsLoaded": [
{
"matcher": "",
"hooks": [
{
"type": "command",
"command": "/Users/junaidrahim/Code/sandbox/log-hook.sh"
}
]
}
],
"ConfigChange": [
{
"matcher": "",
"hooks": [
{
"type": "command",
"command": "/Users/junaidrahim/Code/sandbox/log-hook.sh"
}
]
}
],
"CwdChanged": [
{
"matcher": "",
"hooks": [
{
"type": "command",
"command": "/Users/junaidrahim/Code/sandbox/log-hook.sh"
}
]
}
],
"FileChanged": [
{
"matcher": "",
"hooks": [
{
"type": "command",
"command": "/Users/junaidrahim/Code/sandbox/log-hook.sh"
}
]
}
],
"WorktreeCreate": [
{
"matcher": "",
"hooks": [
{
"type": "command",
"command": "/Users/junaidrahim/Code/sandbox/log-hook.sh"
}
]
}
],
"WorktreeRemove": [
{
"matcher": "",
"hooks": [
{
"type": "command",
"command": "/Users/junaidrahim/Code/sandbox/log-hook.sh"
}
]
}
],
"PreCompact": [
{
"matcher": "",
"hooks": [
{
"type": "command",
"command": "/Users/junaidrahim/Code/sandbox/log-hook.sh"
}
]
}
],
"PostCompact": [
{
"matcher": "",
"hooks": [
{
"type": "command",
"command": "/Users/junaidrahim/Code/sandbox/log-hook.sh"
}
]
}
],
"Elicitation": [
{
"matcher": "",
"hooks": [
{
"type": "command",
"command": "/Users/junaidrahim/Code/sandbox/log-hook.sh"
}
]
}
],
"ElicitationResult": [
{
"matcher": "",
"hooks": [
{
"type": "command",
"command": "/Users/junaidrahim/Code/sandbox/log-hook.sh"
}
]
}
],
"SessionEnd": [
{
"matcher": "",
"hooks": [
{
"type": "command",
"command": "/Users/junaidrahim/Code/sandbox/log-hook.sh"
}
]
}
]
}
}
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
clu_cli-1.24.0.tar.gz
(62.6 kB
view details)
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
clu_cli-1.24.0-py3-none-any.whl
(68.5 kB
view details)
File details
Details for the file clu_cli-1.24.0.tar.gz.
File metadata
- Download URL: clu_cli-1.24.0.tar.gz
- Upload date:
- Size: 62.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
uv/0.11.14 {"installer":{"name":"uv","version":"0.11.14","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f1ce8bae52de8d97bbda65c55e5c46510cd0b8021328edae94c9059be42af22f
|
|
| MD5 |
6578972cd7cb2f8bf37e3a4b83df6a4d
|
|
| BLAKE2b-256 |
956380b75ce1d89e60a490c8902f478ff0da3ec1859e0339d8d25f37e13222aa
|
File details
Details for the file clu_cli-1.24.0-py3-none-any.whl.
File metadata
- Download URL: clu_cli-1.24.0-py3-none-any.whl
- Upload date:
- Size: 68.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
uv/0.11.14 {"installer":{"name":"uv","version":"0.11.14","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b8e7f2f173922b41f9209dad89f0d7f2ef57f05f485d094f0036135a077d78ee
|
|
| MD5 |
77fd12705e64edfdb9f95f5ed9b72ed7
|
|
| BLAKE2b-256 |
884dfa47e2289030d4230bd3483a2f5f8b2fc19a44e1c37c4b3715d3386ba99a
|