StandupBot
Generate standup updates from recent git activity with a local Ollama model or Groq's free cloud tier.
What is new (unreleased)
Since 0.2.4: a full security/correctness audit (private-IP redaction, a config-mutation bug that could leak an API key across process calls, a broken Linux systemd unit, and a few other fixes), plus a follow-up fix for missing secret-detection patterns (GitHub tokens, AWS keys, Slack tokens, LLM API keys, credentialed URIs) reported via #2. See CHANGELOG.md for the full list.
Quick Start
# Install dependencies
pip install -e .
# Configure StandupBot
standup --setup
# Generate a standup
standup
For Ollama, install and pull a model first:
ollama pull llama3
Providers
| Provider | Cost | Privacy | Best for |
|---|---|---|---|
| Ollama | Free | Fully local | Private, offline workflows |
| Groq | Free tier | Cloud | Fast generation without local model setup |
Groq API keys should be supplied through GROQ_API_KEY when possible.
Core Commands
# Standard generation
standup
standup --hours 48
standup --week
standup --provider groq
# Output options
standup --copy
standup --slack
standup --raw
standup --template slack
standup --verbose
# Cache and filtering controls
standup --no-cache
standup --no-filter
# Maintenance
standup doctor
standup usage
standup logs
standup logs --tail 50
standup logs --clear
standup models
standup templates
standup history
standup history --limit 25
standup history --clear
standup history --clear --days 30
standup warm-up
standup warm-up --install-startup
standup warm-up --uninstall-startup
standup --maintenance
Templates
Built-in templates:
defaultslackminimaldetailedjira
You can also define custom templates in config. StandupBot extracts yesterday, today, and blockers from the LLM output, then renders the final format with these variables:
{yesterday}{today}{blockers}{date}{time}{commit_count}{repos}{provider}{author_email}
Config
StandupBot reads ~/.standup.json.
{
"repos": [
"/path/to/repo1",
"/path/to/repo2"
],
"author_email": "you@example.com",
"hours_lookback": 24,
"tone": "casual",
"slack_webhook_url": "",
"provider": {
"name": "ollama",
"ollama": {
"base_url": "http://localhost:11434",
"model": "llama3"
},
"groq": {
"api_key": "",
"model": "llama-3.1-8b-instant"
}
},
"rate_limit": {
"cooldown_minutes": 30,
"max_calls_per_day": 10,
"enabled": true
},
"quality": {
"enabled": true,
"min_score": 0,
"show_breakdown": false
},
"noise_filter_enabled": true,
"template": "default",
"custom_templates": {
"my_format": "Done: {yesterday} | Doing: {today} | Help needed: {blockers}"
},
"auto_warm_up": false
}
Caching and History
Every generated standup is stored locally in ~/.standup_history.db.
- Cache keys are based on a SHA256 fingerprint of sorted commit hashes.
- Cache reuse is limited to the same day, tone, and provider.
- The database stores standup text, provider metadata, repo names, lookback hours, and quality score.
- Raw commit messages are not stored in the database.
Quality Scoring
After generation, StandupBot can score the standup from 0-100 and show a colored badge.
- Green: 80+
- Yellow: 60-79
- Red: below 60
When quality.min_score is above zero, StandupBot retries low-quality outputs up to two times with refined guidance.
Warm-Up
Use standup warm-up to pre-load the configured model before your first real run.
- Ollama: sends a minimal warm-up request to keep the selected model ready in memory.
- Groq: runs a lightweight availability ping.
auto_warm_upcan trigger a silent warm-up when the model has not been used recently.
Security
StandupBot treats config, git metadata, templates, provider responses, and local storage as hostile inputs until proven otherwise.
~/.standup.json,~/.standup_usage.json,~/.standup_history.db, and~/.standup.loguse restricted permissions on Unix/macOS.- Commit messages are scanned for common secret formats — passwords/tokens/API keys, private IPs, internal hostnames, bearer tokens, GitHub PATs, LLM provider keys, AWS access keys, Slack tokens, and credentialed URIs — and redacted before they reach a prompt, storage, or the terminal.
- Repo paths go through explicit path-safety checks to block traversal tricks, network paths, and unsafe symlinks.
- Commit messages and LLM responses are length-capped before they reach prompts, storage, or terminal rendering.
- Custom templates only substitute a fixed allowlist of variables and reject Python-style format syntax.
- All history database queries are parameterized, and stored standup text is sanitized before persistence.
- User-facing exception messages are sanitized so file paths, emails, and API-key-shaped values are not echoed back to the terminal.
standup doctornow checks log health, DB size, schema version, WAL mode, file permissions, and full config validity.
Development
python -m pytest tests/ -q
If your environment restricts Python temp directories or __pycache__ writes, set a writable --basetemp or PYTHONDONTWRITEBYTECODE=1 while testing.
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
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
File details
Details for the file standup_bot-0.2.6.tar.gz.
File metadata
- Download URL: standup_bot-0.2.6.tar.gz
- Upload date:
- Size: 84.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
581203107da3f4e7b09a48b80b0a96c680d23c6348756f76e30f197858ba6903
|
|
| MD5 |
fb0cac8d6a628456bc9ff2b949b70216
|
|
| BLAKE2b-256 |
6f2e8fb17cd1c5a371cbc6493b18c3369675d7f21e0aab01a923652b560e9d31
|
Provenance
The following attestation bundles were made for standup_bot-0.2.6.tar.gz:
Publisher:
release.yml on SemTiOne/standup-bot
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
standup_bot-0.2.6.tar.gz -
Subject digest:
581203107da3f4e7b09a48b80b0a96c680d23c6348756f76e30f197858ba6903 - Sigstore transparency entry: 2279149188
- Sigstore integration time:
-
Permalink:
SemTiOne/standup-bot@e38de29a18771a35378a30d3ff4b5fbe00d83229 -
Branch / Tag:
refs/tags/v0.2.6 - Owner: https://github.com/SemTiOne
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@e38de29a18771a35378a30d3ff4b5fbe00d83229 -
Trigger Event:
push
-
Statement type:
File details
Details for the file standup_bot-0.2.6-py3-none-any.whl.
File metadata
- Download URL: standup_bot-0.2.6-py3-none-any.whl
- Upload date:
- Size: 57.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f69158b0bee782922de956a97c10111cf0dc8e031a732cdc55d2b6b297ab519e
|
|
| MD5 |
02c50f264c526a7e02585d6ebd3dc10a
|
|
| BLAKE2b-256 |
85d11e96204e7ca408b6b2c9ab6e523912b5f406a9adf0781ec9ace9b3603689
|
Provenance
The following attestation bundles were made for standup_bot-0.2.6-py3-none-any.whl:
Publisher:
release.yml on SemTiOne/standup-bot
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
standup_bot-0.2.6-py3-none-any.whl -
Subject digest:
f69158b0bee782922de956a97c10111cf0dc8e031a732cdc55d2b6b297ab519e - Sigstore transparency entry: 2279149202
- Sigstore integration time:
-
Permalink:
SemTiOne/standup-bot@e38de29a18771a35378a30d3ff4b5fbe00d83229 -
Branch / Tag:
refs/tags/v0.2.6 - Owner: https://github.com/SemTiOne
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@e38de29a18771a35378a30d3ff4b5fbe00d83229 -
Trigger Event:
push
-
Statement type: