term-pet 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. term_pet-0.1.0/.gitignore +51 -0
  2. term_pet-0.1.0/LICENSE +21 -0
  3. term_pet-0.1.0/PKG-INFO +493 -0
  4. term_pet-0.1.0/README.md +430 -0
  5. term_pet-0.1.0/pyproject.toml +133 -0
  6. term_pet-0.1.0/src/tpet/__init__.py +3 -0
  7. term_pet-0.1.0/src/tpet/__main__.py +5 -0
  8. term_pet-0.1.0/src/tpet/animation/__init__.py +8 -0
  9. term_pet-0.1.0/src/tpet/animation/engine.py +130 -0
  10. term_pet-0.1.0/src/tpet/app.py +285 -0
  11. term_pet-0.1.0/src/tpet/art/__init__.py +43 -0
  12. term_pet-0.1.0/src/tpet/art/client.py +123 -0
  13. term_pet-0.1.0/src/tpet/art/detect.py +31 -0
  14. term_pet-0.1.0/src/tpet/art/generator.py +608 -0
  15. term_pet-0.1.0/src/tpet/art/openai_client.py +240 -0
  16. term_pet-0.1.0/src/tpet/art/process.py +456 -0
  17. term_pet-0.1.0/src/tpet/art/storage.py +285 -0
  18. term_pet-0.1.0/src/tpet/cli.py +867 -0
  19. term_pet-0.1.0/src/tpet/commentary/__init__.py +8 -0
  20. term_pet-0.1.0/src/tpet/commentary/generator.py +348 -0
  21. term_pet-0.1.0/src/tpet/commentary/prompts.py +78 -0
  22. term_pet-0.1.0/src/tpet/config.py +410 -0
  23. term_pet-0.1.0/src/tpet/io.py +63 -0
  24. term_pet-0.1.0/src/tpet/llm_client.py +80 -0
  25. term_pet-0.1.0/src/tpet/models/__init__.py +13 -0
  26. term_pet-0.1.0/src/tpet/models/pet.py +36 -0
  27. term_pet-0.1.0/src/tpet/models/rarity.py +73 -0
  28. term_pet-0.1.0/src/tpet/models/stats.py +41 -0
  29. term_pet-0.1.0/src/tpet/monitor/__init__.py +12 -0
  30. term_pet-0.1.0/src/tpet/monitor/parser.py +156 -0
  31. term_pet-0.1.0/src/tpet/monitor/text_watcher.py +120 -0
  32. term_pet-0.1.0/src/tpet/monitor/watcher.py +162 -0
  33. term_pet-0.1.0/src/tpet/profile/__init__.py +11 -0
  34. term_pet-0.1.0/src/tpet/profile/generator.py +624 -0
  35. term_pet-0.1.0/src/tpet/profile/storage.py +73 -0
  36. term_pet-0.1.0/src/tpet/py.typed +0 -0
  37. term_pet-0.1.0/src/tpet/renderer/__init__.py +11 -0
  38. term_pet-0.1.0/src/tpet/renderer/card.py +159 -0
  39. term_pet-0.1.0/src/tpet/renderer/display.py +221 -0
  40. term_pet-0.1.0/src/tpet/renderer/preview.py +119 -0
  41. term_pet-0.1.0/src/tpet/renderer/protocol.py +136 -0
  42. term_pet-0.1.0/src/tpet/renderer/statbars.py +32 -0
@@ -0,0 +1,51 @@
1
+ # Python
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+ *.egg-info/
6
+ *.egg
7
+
8
+ # Build
9
+ dist/
10
+ build/
11
+
12
+ # Virtual environments
13
+ .venv/
14
+
15
+ # Testing & linting
16
+ .pytest_cache/
17
+ .ruff_cache/
18
+ .pyright/
19
+ .coverage
20
+ htmlcov/
21
+
22
+ # OS
23
+ .DS_Store
24
+ Thumbs.db
25
+
26
+ # IDEs
27
+ .idea/
28
+ .vscode/
29
+ *.swp
30
+ *.swo
31
+
32
+ # Logs
33
+ *.log
34
+
35
+ # Claude Code (keep .claude/ itself)
36
+ *-mcp.json
37
+ .gemini-clipboard
38
+ .cc2cc-session-id
39
+ claude_scratch/
40
+ settings.local.json
41
+ CLAUDE.local.md
42
+ *.local
43
+ *.local.*
44
+ .superpowers/
45
+
46
+ # tpet runtime
47
+ .tpet/
48
+ .env
49
+ *~
50
+ *.bak
51
+ scripts/ollama_art_report.html
term_pet-0.1.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Paul Robello
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,493 @@
1
+ Metadata-Version: 2.4
2
+ Name: term-pet
3
+ Version: 0.1.0
4
+ Summary: A terminal pet companion that monitors Claude Code sessions
5
+ Project-URL: Homepage, https://github.com/paulrobello/tpet
6
+ Project-URL: Documentation, https://github.com/paulrobello/tpet/blob/main/README.md
7
+ Project-URL: Source, https://github.com/paulrobello/tpet
8
+ Project-URL: Issues, https://github.com/paulrobello/tpet/issues
9
+ Author-email: Paul Robello <probello@gmail.com>
10
+ Maintainer-email: Paul Robello <probello@gmail.com>
11
+ License: MIT License
12
+
13
+ Copyright (c) 2026 Paul Robello
14
+
15
+ Permission is hereby granted, free of charge, to any person obtaining a copy
16
+ of this software and associated documentation files (the "Software"), to deal
17
+ in the Software without restriction, including without limitation the rights
18
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
19
+ copies of the Software, and to permit persons to whom the Software is
20
+ furnished to do so, subject to the following conditions:
21
+
22
+ The above copyright notice and this permission notice shall be included in all
23
+ copies or substantial portions of the Software.
24
+
25
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
26
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
27
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
28
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
29
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
30
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
31
+ SOFTWARE.
32
+ License-File: LICENSE
33
+ Keywords: ai,ascii,claude,llm,ollama,pet,terminal,tui
34
+ Classifier: Development Status :: 4 - Beta
35
+ Classifier: Environment :: Console
36
+ Classifier: Intended Audience :: Developers
37
+ Classifier: Intended Audience :: End Users/Desktop
38
+ Classifier: Intended Audience :: Other Audience
39
+ Classifier: License :: OSI Approved :: MIT License
40
+ Classifier: Operating System :: MacOS
41
+ Classifier: Operating System :: Microsoft :: Windows :: Windows 10
42
+ Classifier: Operating System :: Microsoft :: Windows :: Windows 11
43
+ Classifier: Operating System :: POSIX :: Linux
44
+ Classifier: Programming Language :: Python :: 3
45
+ Classifier: Programming Language :: Python :: 3.13
46
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
47
+ Classifier: Topic :: Terminals
48
+ Classifier: Typing :: Typed
49
+ Requires-Python: >=3.13
50
+ Requires-Dist: claude-agent-sdk>=0.1.54
51
+ Requires-Dist: google-genai>=1.57.0
52
+ Requires-Dist: numpy>=2.0
53
+ Requires-Dist: openai>=1.82
54
+ Requires-Dist: pillow>=11.0
55
+ Requires-Dist: pydantic>=2.12
56
+ Requires-Dist: python-dotenv>=1.0
57
+ Requires-Dist: pyyaml>=6.0
58
+ Requires-Dist: rich>=14
59
+ Requires-Dist: typer>=0.24
60
+ Requires-Dist: watchdog>=6.0
61
+ Requires-Dist: xdg-base-dirs>=6.0
62
+ Description-Content-Type: text/markdown
63
+
64
+ # TPET - Terminal Pet Companion
65
+
66
+ A terminal pet that monitors your Claude Code sessions and generates personality-driven commentary. Runs in a tmux pane with ASCII art animation and Rich rendering.
67
+
68
+ ## Table of Contents
69
+
70
+ * [About](#about)
71
+ * [Screenshots](#screenshots)
72
+ * [Features](#features)
73
+ * [Core Capabilities](#core-capabilities)
74
+ * [Art Modes](#art-modes)
75
+ * [Technical Excellence](#technical-excellence)
76
+ * [Prerequisites](#prerequisites)
77
+ * [Installing using uv (recommended)](#using-uv)
78
+ * [Installing using pipx](#pipx)
79
+ * [Installing for dev mode](#installing-for-dev-mode)
80
+ * [Usage](#usage)
81
+ * [CLI Reference](#cli-reference)
82
+ * [Global flags](#global-flags)
83
+ * [tpet new](#tpet-new)
84
+ * [tpet details](#tpet-details)
85
+ * [tpet art](#tpet-art)
86
+ * [tpet run](#tpet-run)
87
+ * [Legacy flags](#legacy-flag-style)
88
+ * [Configuration](#configuration)
89
+ * [Pipeline provider configuration](#pipeline-provider-configuration)
90
+ * [General configuration reference](#general-configuration-reference)
91
+ * [Environment Variables](#environment-variables)
92
+ * [How It Works](#how-it-works)
93
+ * [Development](#development)
94
+ * [Contributing](#contributing)
95
+ * [License](#license)
96
+
97
+ [![PyPI](https://img.shields.io/pypi/v/term-pet)](https://pypi.org/project/term-pet/)
98
+ [![PyPI - Python Version](https://img.shields.io/pypi/pyversions/term-pet.svg)](https://pypi.org/project/term-pet/)
99
+ ![Runs on Linux | MacOS | Windows](https://img.shields.io/badge/runs%20on-Linux%20%7C%20MacOS%20%7C%20Windows-blue)
100
+ ![Arch x86-64 | ARM | AppleSilicon](https://img.shields.io/badge/arch-x86--64%20%7C%20ARM%20%7C%20AppleSilicon-blue)
101
+ ![PyPI - License](https://img.shields.io/pypi/l/term-pet)
102
+
103
+ ## Screenshots
104
+
105
+ **ASCII mode — live commentary**
106
+
107
+ <img src="https://raw.githubusercontent.com/paulrobello/tpet/main/pet-ascii-screenshot.png" alt="ASCII mode live session" width="600">
108
+
109
+ **ASCII mode — pet details card**
110
+
111
+ <img src="https://raw.githubusercontent.com/paulrobello/tpet/main/pet-ascii-details-screenshot.png" alt="ASCII mode details card" width="600">
112
+
113
+ **Sixel mode — live commentary**
114
+
115
+ <img src="https://raw.githubusercontent.com/paulrobello/tpet/main/pet-sixel-screenshot.png" alt="Sixel mode live session" width="600">
116
+
117
+ **Sixel mode — pet details card**
118
+
119
+ <img src="https://raw.githubusercontent.com/paulrobello/tpet/main/pet-sixel-details-screenshot.png" alt="Sixel mode details card" width="600">
120
+
121
+ ## About
122
+
123
+ I really liked the idea of the Claude Code buddy so I created my own that supports infinite variations and customization. It even supports watching plain files and commenting on them!
124
+
125
+ tpet is a CLI application that creates a unique AI-generated pet creature. The pet displays in your terminal using Rich Live rendering, monitors your Claude Code session JSONL files (or plain text files) via watchdog, and produces in-character commentary about your coding sessions.
126
+
127
+ Built with [Typer](https://typer.tiangolo.com/), [Rich](https://github.com/Textualize/rich), and the [Claude Agent SDK](https://github.com/anthropics/claude-agent-sdk).
128
+
129
+ [!["Buy Me A Coffee"](https://www.buymeacoffee.com/assets/img/custom_images/orange_img.png)](https://buymeacoffee.com/probello3)
130
+
131
+ ## Features
132
+
133
+ ### Core Capabilities
134
+ - **AI-Generated Pets**: Each pet is unique -- name, personality, ASCII art, backstory, and stats all generated by the LLM
135
+ - **Personality-Driven Stats**: HUMOR, PATIENCE, CHAOS, WISDOM, SNARK -- generated to match the creature's character and clamped by rarity tier
136
+ - **Rarity System**: Common, Uncommon, Rare, and Legendary tiers determine stat ranges and display colors
137
+ - **Session Monitoring**: Watches Claude Code JSONL sessions via watchdog or follows plain text files with `--follow`
138
+ - **In-Character Commentary**: Session events trigger personality-driven reactions influenced by the pet's stats
139
+ - **Idle Chatter**: When nothing is happening, your pet comments on its own
140
+
141
+ ### Art Modes
142
+ - **ASCII (default)**: Character art generated by the LLM, displayed with Rich
143
+ - **Sixel Art**: AI-generated sprites rendered as ANSI half-block characters (requires API key)
144
+ - **Custom Base Images**: Supply your own idle frame image with `--base-image`
145
+
146
+ ### Technical Excellence
147
+ - **No API Key Required**: Commentary and pet generation use your Claude Code subscription via the Agent SDK
148
+ - **Per-Pipeline Providers**: Independently configure the provider/model for profile generation, commentary, and image art
149
+ - **Multiple Providers**: Claude (Agent SDK), Ollama, OpenAI, OpenRouter, and Google Gemini for any pipeline
150
+ - **Non-Blocking Commentary**: Background `ThreadPoolExecutor` keeps the 4fps display smooth during LLM calls
151
+ - **YAML Persistence**: Human-readable config and profiles via Pydantic serialization
152
+ - **XDG Compliance**: Config and data paths follow XDG base directory conventions
153
+
154
+ ## Prerequisites
155
+ * Install and authenticate [Claude Code](https://docs.anthropic.com/en/docs/claude-code) (required for default commentary and pet generation)
156
+ * Install Python 3.13 or newer
157
+ * [https://www.python.org/downloads/](https://www.python.org/downloads/) has installers for all platforms
158
+ * On macOS with Homebrew: `brew install python@3.13`
159
+
160
+ ## Using uv
161
+
162
+ The recommended way to install tpet. If you don't have uv installed:
163
+ ```bash
164
+ curl -LsSf https://astral.sh/uv/install.sh | sh
165
+ ```
166
+
167
+ ### PyPi install
168
+ ```bash
169
+ uv tool install term-pet
170
+ ```
171
+
172
+ To upgrade:
173
+ ```bash
174
+ uv tool install term-pet -U --force
175
+ ```
176
+
177
+ ### Installing / running using uvx
178
+ ```bash
179
+ uvx --from term-pet tpet
180
+ ```
181
+
182
+ ### Source install from GitHub
183
+ ```bash
184
+ uv tool install git+https://github.com/paulrobello/tpet
185
+ ```
186
+
187
+ To upgrade:
188
+ ```bash
189
+ uv tool install git+https://github.com/paulrobello/tpet -U --force
190
+ ```
191
+
192
+ ## pipx
193
+
194
+ ### Installing
195
+ If you don't have pipx installed:
196
+ ```bash
197
+ pip install pipx
198
+ pipx ensurepath
199
+ ```
200
+
201
+ ### PyPi install
202
+ ```bash
203
+ pipx install term-pet
204
+ ```
205
+
206
+ To upgrade an existing installation:
207
+ ```bash
208
+ pipx install term-pet --force
209
+ ```
210
+
211
+ ### Source install from GitHub
212
+ ```bash
213
+ pipx install git+https://github.com/paulrobello/tpet
214
+ ```
215
+
216
+ To upgrade:
217
+ ```bash
218
+ pipx install git+https://github.com/paulrobello/tpet --force
219
+ ```
220
+
221
+ ## Installing for dev mode
222
+
223
+ Clone the repo and run the setup make target. Note `uv` is required.
224
+ ```bash
225
+ git clone https://github.com/paulrobello/tpet
226
+ cd tpet
227
+ make setup
228
+ ```
229
+
230
+ ## Usage
231
+
232
+ tpet uses subcommands for distinct operations. The old flag-based style (`--new`, `--details`, `--gen-art`, etc.) still works for backward compatibility.
233
+
234
+ ```bash
235
+ # Subcommand style (preferred)
236
+ tpet run # Start the live pet display (default if no subcommand)
237
+ tpet run --follow /path/to/file # Follow a plain text file instead of Claude sessions
238
+ tpet new # Generate a new pet
239
+ tpet new -y # Generate without confirmation
240
+ tpet new -C "make it a dragon" # Generate with custom criteria
241
+ tpet details # Show full pet card
242
+ tpet details --backstory # Show card with backstory
243
+ tpet art # Generate graphical art for the current pet
244
+ tpet art --art-mode sixel-art # Generate sixel art specifically
245
+
246
+ # Flag style (backward-compatible)
247
+ tpet # Start the pet (watches Claude Code sessions)
248
+ tpet --new # Generate a new pet
249
+ tpet --details # Show full pet card
250
+ tpet --gen-art # Generate graphical art
251
+ tpet --reset # Delete current pet
252
+ tpet --reset -y # Delete without confirmation
253
+ tpet --dump-config # Show current config
254
+ tpet --project /path/to/repo # Use project-specific pet
255
+ tpet --dry-run # Validate config and exit
256
+ tpet --regen-art # Regenerate ASCII art for current pet
257
+ ```
258
+
259
+ ## CLI Reference
260
+
261
+ ### Global flags
262
+
263
+ | Flag | Short | Description |
264
+ |------|-------|-------------|
265
+ | `--version` | | Show version |
266
+ | `--debug` | `-D` | Enable debug logging |
267
+ | `--verbose` | `-v` | Increase verbosity (stackable) |
268
+ | `--project` | `-p` | Project directory |
269
+ | `--config-dir` | `-c` | Config directory override |
270
+
271
+ ### tpet new
272
+ Generate a new pet.
273
+
274
+ | Flag | Short | Description |
275
+ |------|-------|-------------|
276
+ | `--create-prompt` | `-C` | Custom criteria for pet generation |
277
+ | `--create-prompt-file` | `-F` | File containing custom criteria |
278
+ | `--yes` | `-y` | Bypass confirmation prompts |
279
+ | `--seed` | `-s` | Random seed for pet generation (defaults to current time) |
280
+
281
+ ### tpet details
282
+ Show the pet details card.
283
+
284
+ | Flag | Short | Description |
285
+ |------|-------|-------------|
286
+ | `--backstory` | `-b` | Include backstory in card |
287
+
288
+ ### tpet art
289
+ Generate graphical art for the current pet.
290
+
291
+ | Flag | Short | Description |
292
+ |------|-------|-------------|
293
+ | `--art-mode` | `-a` | Art display mode: `ascii` or `sixel-art` |
294
+ | `--art-provider` | `-P` | Image art provider: `openai`, `gemini`, or `openrouter` |
295
+ | `--art-model` | | Model for image art generation |
296
+ | `--art-width` | `-W` | Max percentage of terminal width for art (1-100) |
297
+ | `--art-prompt` | | Custom prompt for image generation |
298
+ | `--base-image` | | Custom image to use as idle frame (forces OpenAI edits) |
299
+
300
+ ### tpet run
301
+ Start the live pet display (default mode).
302
+
303
+ | Flag | Short | Description |
304
+ |------|-------|-------------|
305
+ | `--follow` | `-f` | Follow a plain text file instead of Claude sessions |
306
+ | `--watch-dir` | `-w` | Session watch directory override |
307
+ | `--commentary-provider` | | Commentary LLM provider: `claude`, `ollama`, `openai`, `openrouter`, or `gemini` |
308
+ | `--commentary-model` | | Model for commentary generation |
309
+ | `--comment-interval` | `-i` | Min seconds between comments |
310
+ | `--idle-chatter-interval` | `-I` | Seconds between idle chatter |
311
+ | `--max-comments` | `-M` | Max comments per session |
312
+ | `--sleep-threshold` | `-s` | Seconds before sleep animation |
313
+ | `--art-mode` | `-a` | Art display mode: `ascii` or `sixel-art` |
314
+ | `--log-level` | `-l` | Log level override |
315
+ | `--show-session` | | Show resolved session directory and file, then exit |
316
+
317
+ ### Legacy flag-style
318
+
319
+ The root `tpet` command accepts all flags from every subcommand for backward compatibility. For example, `tpet --new`, `tpet --details`, `tpet --gen-art`, `tpet --reset`, `tpet --regen-art`, `tpet --dump-config`, and `tpet --dry-run` all continue to work as before.
320
+
321
+ ## Configuration
322
+
323
+ Config file: `~/.config/tpet/config.yaml`
324
+
325
+ ```yaml
326
+ # Per-pipeline LLM provider configuration
327
+ profile_provider_config:
328
+ provider: claude
329
+ model: claude-haiku-4-5
330
+
331
+ commentary_provider_config:
332
+ provider: claude
333
+ model: claude-haiku-4-5
334
+
335
+ image_art_provider_config:
336
+ provider: openai
337
+ model: gpt-image-1.5
338
+
339
+ # Timing
340
+ comment_interval_seconds: 30
341
+ idle_chatter_interval_seconds: 300
342
+ max_comments_per_session: 0
343
+ max_comment_length: 150
344
+ max_idle_length: 100
345
+ sleep_threshold_seconds: 120
346
+
347
+ # Animation
348
+ idle_duration_seconds: 3.0
349
+ reaction_duration_seconds: 0.5
350
+ sleep_duration_seconds: 60.0
351
+ ascii_art_frames: 6
352
+
353
+ # Display
354
+ art_mode: ascii
355
+ art_max_width_pct: 40
356
+ art_size: 120
357
+ halfblock_size: 48
358
+ bubble_placement: bottom
359
+
360
+ # Art processing
361
+ chroma_tolerance: 30
362
+ art_dir_path: art
363
+ art_prompt: ""
364
+
365
+ # Logging
366
+ log_level: WARNING
367
+ log_file: debug.log
368
+ ```
369
+
370
+ ### Pipeline provider configuration
371
+
372
+ Each pipeline (`profile_provider_config`, `commentary_provider_config`, `image_art_provider_config`) independently configures its own LLM provider:
373
+
374
+ | Field | Type | Default | Description |
375
+ |-------|------|---------|-------------|
376
+ | `provider` | string | `claude` | LLM provider: `claude`, `ollama`, `openai`, `openrouter`, or `gemini` |
377
+ | `model` | string | *(provider default)* | Model override (empty = provider default) |
378
+ | `base_url` | string | *(provider default)* | API base URL override (empty = provider default) |
379
+ | `api_key_env` | string | *(provider default)* | Environment variable name for the API key |
380
+
381
+ Provider defaults:
382
+
383
+ | Provider | Text default model | Image default model | Default base URL |
384
+ |----------|-------------------|---------------------|------------------|
385
+ | `claude` | `claude-haiku-4-5` | *(n/a)* | Agent SDK (no URL) |
386
+ | `ollama` | `llama3.2` | *(n/a)* | `http://localhost:11434/v1` |
387
+ | `openai` | `gpt-4o` | `gpt-image-1.5` | `https://api.openai.com/v1` |
388
+ | `openrouter` | `anthropic/claude-haiku-4-5` | `openai/dall-e-3` | `https://openrouter.ai/api/v1` |
389
+ | `gemini` | `gemini-2.5-flash` | `gemini-2.5-flash` | Google Genai client |
390
+
391
+ ### General configuration reference
392
+
393
+ | Field | Type | Default | Description |
394
+ |-------|------|---------|-------------|
395
+ | `comment_interval_seconds` | float | `30.0` | Minimum seconds between event-triggered comments |
396
+ | `idle_chatter_interval_seconds` | float | `300.0` | Seconds of inactivity before idle chatter |
397
+ | `max_comments_per_session` | int | `0` | Maximum comments per run (0 = unlimited) |
398
+ | `max_comment_length` | int | `150` | Character limit for event comments |
399
+ | `max_idle_length` | int | `100` | Character limit for idle chatter |
400
+ | `log_level` | string | `WARNING` | Log verbosity: `DEBUG`, `INFO`, `WARNING`, `ERROR` |
401
+ | `log_file` | string | `debug.log` | Log filename (written inside the config directory) |
402
+ | `sleep_threshold_seconds` | int | `120` | Inactivity seconds before sleep animation |
403
+ | `idle_duration_seconds` | float | `3.0` | Seconds per idle animation frame cycle |
404
+ | `reaction_duration_seconds` | float | `0.5` | Duration of the reaction animation |
405
+ | `sleep_duration_seconds` | float | `60.0` | Duration of each sleep animation cycle |
406
+ | `ascii_art_frames` | int | `6` | Number of animation frames per pet |
407
+ | `art_mode` | string | `ascii` | Display mode: `ascii` or `sixel-art` |
408
+ | `art_max_width_pct` | int | `40` | Percentage of terminal width allocated to the art panel |
409
+ | `art_size` | int | `120` | Target pixel height for art sprites (multiple of 6) |
410
+ | `halfblock_size` | int | `48` | Target pixel height for sixel-art half-blocks (must be even) |
411
+ | `chroma_tolerance` | int | `30` | Chroma key removal tolerance for background removal |
412
+ | `art_dir_path` | string | `art` | Subdirectory name under config dir for art files |
413
+ | `art_prompt` | string | `""` | Custom prompt override for image generation (empty = auto-generate) |
414
+ | `bubble_placement` | string | `bottom` | Speech bubble position: `top`, `right`, or `bottom` |
415
+
416
+ Pet profiles are stored at:
417
+ * Global: `~/.config/tpet/profile.yaml`
418
+ * Per-project: `<project>/.tpet/profile.yaml`
419
+
420
+ ## Environment Variables
421
+
422
+ API keys for graphical art generation and third-party providers are read from environment variables. The recommended approach is to place them in `~/.config/tpet/.env`, which tpet loads automatically on every startup.
423
+
424
+ | Variable | Required for | Description |
425
+ |----------|-------------|-------------|
426
+ | `OPENAI_API_KEY` | `provider: openai` | OpenAI API key for text or image generation |
427
+ | `GEMINI_API_KEY` | `provider: gemini` | Google Gemini API key for text or image generation |
428
+ | `OPENROUTER_API_KEY` | `provider: openrouter` | OpenRouter API key for any pipeline |
429
+
430
+ Example `~/.config/tpet/.env`:
431
+
432
+ ```bash
433
+ OPENAI_API_KEY=sk-proj-...
434
+ GEMINI_API_KEY=AIza...
435
+ OPENROUTER_API_KEY=sk-or-...
436
+ ```
437
+
438
+ No API key is required for the default `claude` provider or for ASCII art mode -- the Claude provider uses your Claude Code subscription via the Agent SDK. Ollama runs locally and requires no key.
439
+
440
+ ## How It Works
441
+
442
+ 1. On first run, tpet generates a unique pet using the LLM (name, personality, ASCII art, backstory)
443
+ 2. Stats (HUMOR, PATIENCE, CHAOS, WISDOM, SNARK) are personality-driven -- generated by the LLM to match the creature's character, then clamped to the rarity range
444
+ 3. The pet's rarity (Common/Uncommon/Rare/Legendary) determines stat ranges and display colors
445
+ 4. By default, tpet monitors your Claude Code session's JSONL files via watchdog (use `--follow` to watch a plain text file instead)
446
+ 5. Session events trigger in-character commentary influenced by the pet's personality and stats
447
+ 6. The pet animates through a 6-frame cycle: idle, idle-shift, blink, blink-shift, react, and sleep. Blink frames are generated programmatically by compositing the idle pose with closed eyes from the sleep frame
448
+ 7. On exit, tpet prints a session summary showing total comments, API calls, token counts, and estimated cost
449
+
450
+ ## Development
451
+
452
+ ```bash
453
+ make checkall # Run all checks (fmt, lint, typecheck, test)
454
+ make test # Run tests only
455
+ make lint # Lint with ruff
456
+ make fmt # Format with ruff
457
+ make typecheck # Type check with pyright
458
+ ```
459
+
460
+ ### Dev mode
461
+ From repo root:
462
+ ```bash
463
+ make dev
464
+ ```
465
+
466
+ ## Contributing
467
+
468
+ Please ensure that all pull requests are formatted with ruff, pass ruff lint and pyright.
469
+ You can run the make target `checkall` to ensure the pipeline will pass with your changes.
470
+
471
+ The easiest way to setup your environment:
472
+
473
+ With uv installed:
474
+ ```bash
475
+ uv tool install pre-commit
476
+ ```
477
+
478
+ With pipx installed:
479
+ ```bash
480
+ pipx install pre-commit
481
+ ```
482
+
483
+ From repo root:
484
+ ```bash
485
+ pre-commit install
486
+ pre-commit run --all-files
487
+ ```
488
+
489
+ After running the above, all future commits will auto run pre-commit. Pre-commit will fix what it can and show what remains to be fixed.
490
+
491
+ ## License
492
+
493
+ MIT -- see [LICENSE](LICENSE) for details.