termstory 0.2.5__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.
- termstory-0.2.5/LICENSE +21 -0
- termstory-0.2.5/MANIFEST.in +3 -0
- termstory-0.2.5/PKG-INFO +636 -0
- termstory-0.2.5/README.md +614 -0
- termstory-0.2.5/pyproject.toml +35 -0
- termstory-0.2.5/setup.cfg +4 -0
- termstory-0.2.5/setup.py +31 -0
- termstory-0.2.5/termstory/__init__.py +2 -0
- termstory-0.2.5/termstory/__main__.py +4 -0
- termstory-0.2.5/termstory/ai.py +486 -0
- termstory-0.2.5/termstory/cli.py +228 -0
- termstory-0.2.5/termstory/config.py +208 -0
- termstory-0.2.5/termstory/database.py +792 -0
- termstory-0.2.5/termstory/date_utils.py +55 -0
- termstory-0.2.5/termstory/formatter.py +1324 -0
- termstory-0.2.5/termstory/git_integration.py +196 -0
- termstory-0.2.5/termstory/insights.py +176 -0
- termstory-0.2.5/termstory/models.py +86 -0
- termstory-0.2.5/termstory/parser.py +237 -0
- termstory-0.2.5/termstory/project.py +245 -0
- termstory-0.2.5/termstory/sanitizer.py +137 -0
- termstory-0.2.5/termstory/session.py +61 -0
- termstory-0.2.5/termstory/templates/example_daily_chronicle.txt +39 -0
- termstory-0.2.5/termstory/tui.py +2370 -0
- termstory-0.2.5/termstory.egg-info/PKG-INFO +636 -0
- termstory-0.2.5/termstory.egg-info/SOURCES.txt +44 -0
- termstory-0.2.5/termstory.egg-info/dependency_links.txt +1 -0
- termstory-0.2.5/termstory.egg-info/entry_points.txt +2 -0
- termstory-0.2.5/termstory.egg-info/requires.txt +5 -0
- termstory-0.2.5/termstory.egg-info/top_level.txt +1 -0
- termstory-0.2.5/tests/test_ai.py +278 -0
- termstory-0.2.5/tests/test_avatar.py +82 -0
- termstory-0.2.5/tests/test_cli_commands.py +88 -0
- termstory-0.2.5/tests/test_database.py +144 -0
- termstory-0.2.5/tests/test_database_queries.py +50 -0
- termstory-0.2.5/tests/test_date_utils.py +72 -0
- termstory-0.2.5/tests/test_formatter_rich.py +151 -0
- termstory-0.2.5/tests/test_git_integration.py +57 -0
- termstory-0.2.5/tests/test_insights.py +58 -0
- termstory-0.2.5/tests/test_integration.py +6 -0
- termstory-0.2.5/tests/test_parser.py +78 -0
- termstory-0.2.5/tests/test_project.py +100 -0
- termstory-0.2.5/tests/test_sanitizer.py +73 -0
- termstory-0.2.5/tests/test_search.py +73 -0
- termstory-0.2.5/tests/test_session.py +58 -0
- termstory-0.2.5/tests/test_tui.py +752 -0
termstory-0.2.5/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 TermStory Contributors
|
|
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.
|
termstory-0.2.5/PKG-INFO
ADDED
|
@@ -0,0 +1,636 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: termstory
|
|
3
|
+
Version: 0.2.5
|
|
4
|
+
Summary: Local shell history parsing, session grouping, and visual daily chronicle terminal dashboard
|
|
5
|
+
Home-page: https://github.com/atuinsh/termstory
|
|
6
|
+
Author: TermStory Contributors
|
|
7
|
+
License: MIT
|
|
8
|
+
Classifier: Programming Language :: Python :: 3
|
|
9
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
10
|
+
Classifier: Operating System :: OS Independent
|
|
11
|
+
Requires-Python: >=3.9
|
|
12
|
+
Description-Content-Type: text/markdown
|
|
13
|
+
License-File: LICENSE
|
|
14
|
+
Requires-Dist: typer>=0.9.0
|
|
15
|
+
Requires-Dist: python-dateutil>=2.8.2
|
|
16
|
+
Requires-Dist: rich>=13.0.0
|
|
17
|
+
Requires-Dist: textual>=0.50.0
|
|
18
|
+
Requires-Dist: pillow>=10.0.0
|
|
19
|
+
Dynamic: home-page
|
|
20
|
+
Dynamic: license-file
|
|
21
|
+
Dynamic: requires-python
|
|
22
|
+
|
|
23
|
+
# TermStory — Private Developer Reference Manual
|
|
24
|
+
|
|
25
|
+
Welcome to **TermStory**, your personal developer memory engine.
|
|
26
|
+
|
|
27
|
+
This repository parses your shell history (`zsh`/`bash`), groups commands into active work sessions, correlates Git commit messages, and formats them into a high-density, searchable work timeline.
|
|
28
|
+
|
|
29
|
+
This document serves as your complete, detailed reference manual detailing the internal architecture, database schemas, privacy sanitizer pipeline, interactive terminal interface, AI configuration, CLI usage, and local setups.
|
|
30
|
+
|
|
31
|
+
---
|
|
32
|
+
|
|
33
|
+
## Table of Contents
|
|
34
|
+
1. [Core Philosophy](#1-core-philosophy)
|
|
35
|
+
2. [Project Layout & Directory Structure](#2-project-layout--directory-structure)
|
|
36
|
+
3. [Chronological Ingestion Pipeline](#3-chronological-ingestion-pipeline)
|
|
37
|
+
4. [Shell History Parsing Mechanics](#4-shell-history-parsing-mechanics)
|
|
38
|
+
5. [VCS Root Resolution & Project Name Humanization](#5-vcs-root-resolution--project-name-humanization)
|
|
39
|
+
6. [Git Commit Correlation Pipeline](#6-git-commit-correlation-pipeline)
|
|
40
|
+
7. [Database Internals & Schema Reference](#7-database-internals--schema-reference)
|
|
41
|
+
8. [Privacy Sanitizer Pipeline](#8-privacy-sanitizer-pipeline)
|
|
42
|
+
9. [Zero-Dependency LLM API Client](#9-zero-dependency-llm-api-client)
|
|
43
|
+
10. [Interactive TUI Dashboard Layout & Style System](#10-interactive-tui-dashboard-layout--style-system)
|
|
44
|
+
11. [AI Prompts & Narrative Design Rules](#11-ai-prompts--narrative-design-rules)
|
|
45
|
+
12. [CLI Command Reference](#12-cli-command-reference)
|
|
46
|
+
13. [Configuration Reference (`config.json`)](#13-configuration-reference-configjson)
|
|
47
|
+
14. [Developer Verification & Testing Suite](#14-developer-verification--testing-suite)
|
|
48
|
+
15. [Troubleshooting & Personal Customization Hacks](#15-troubleshooting--personal-customization-hacks)
|
|
49
|
+
|
|
50
|
+
---
|
|
51
|
+
|
|
52
|
+
## 1. Core Philosophy
|
|
53
|
+
|
|
54
|
+
TermStory is **not** an audit log, a monitoring tool, or a dry analytics reporter. It is a **developer memory engine** built around these core design tenets:
|
|
55
|
+
|
|
56
|
+
* **Recognize, don't inspect**: Designed to help you instantly recognize what you worked on ("Ah, that was when I fixed container networking on project X") rather than scrolling through a wall of raw `cd`, `ls`, or `git status` commands.
|
|
57
|
+
* **Density over decoration**: The terminal TUI and CLI outputs avoid bloated double borders, rounded corners, or massive empty margins. Spacing is tight, information is dense, and column alignments are clean.
|
|
58
|
+
* **Screenshot-friendly**: Every view in the TUI is designed to fit onto a standard terminal grid and tell a clear, self-contained story of a day, a month, or a project.
|
|
59
|
+
* **Noise reduction**: Filters out routine, repetitive, and context-free commands (`ls`, `cd`, `git status`, `clear`, etc.) while highlighting creative actions (`git commit`, `docker compose up`, schema migrations, unit test executions).
|
|
60
|
+
* **Project Disambiguation & Mapping**: Translates raw directory basenames (like `incubator-hugegraph`) into human-friendly names (`Apache HugeGraph`) and maps untracked workspaces or general commands to a unified `"Other"` category.
|
|
61
|
+
|
|
62
|
+
---
|
|
63
|
+
|
|
64
|
+
## 2. Project Layout & Directory Structure
|
|
65
|
+
|
|
66
|
+
Below is the directory map of the TermStory repository:
|
|
67
|
+
|
|
68
|
+
```
|
|
69
|
+
termstory/
|
|
70
|
+
├── setup.py # Packaging metadata and dependency registrations
|
|
71
|
+
├── requirements.txt # Package list (rich, typer, textual, pytest, etc.)
|
|
72
|
+
├── agents.md # Memory engine active development state & context
|
|
73
|
+
├── DATA_PRIVACY.md # High-level data handling policies for the LLM pipeline
|
|
74
|
+
├── README.md # This master reference document
|
|
75
|
+
├── termstory/ # Source package directory
|
|
76
|
+
│ ├── __init__.py # Module exports
|
|
77
|
+
│ ├── __main__.py # CLI wrapper entry point (allows python3 -m termstory)
|
|
78
|
+
│ ├── cli.py # Typer CLI application: parses command arguments & formats outputs
|
|
79
|
+
│ ├── tui.py # Textual Terminal User Interface dashboard & modals
|
|
80
|
+
│ ├── parser.py # Shell history file reading & cleaning engine
|
|
81
|
+
│ ├── session.py # In-memory command sequencing & timeline sessionizer
|
|
82
|
+
│ ├── project.py # Git/VCS root directory matching & project humanization
|
|
83
|
+
│ ├── git_integration.py # Local subprocess client calling git log & cleaning commit logs
|
|
84
|
+
│ ├── database.py # SQLite wrapper: manages schemas, queries, caching & WAL settings
|
|
85
|
+
│ ├── date_utils.py # Timezones, timestamp conversions, and date calculations
|
|
86
|
+
│ ├── sanitizer.py # Local credentials, token, IP & hostname redaction rules
|
|
87
|
+
│ ├── ai.py # Zero-dependency LLM interface client using urllib.request
|
|
88
|
+
│ ├── insights.py # Calculations for Focus Scores, active times & stats
|
|
89
|
+
│ ├── models.py # Dataclasses representing Session, Project, Command, and Commit
|
|
90
|
+
│ └── formatter.py # Output layout logic, emoji matrices, and Rich styling utils
|
|
91
|
+
└── tests/ # Testing package directory
|
|
92
|
+
├── fixtures/
|
|
93
|
+
│ └── sample_history.txt # Fake history stream for parser tests
|
|
94
|
+
├── test_parser.py # Verifies shell history extraction
|
|
95
|
+
├── test_session.py # Asserts session chunking thresholds
|
|
96
|
+
├── test_project.py # Tests workspace parent root resolution
|
|
97
|
+
├── test_git_integration.py # Mock tests for git log processes
|
|
98
|
+
├── test_database.py # SQLite transaction & connection checks
|
|
99
|
+
├── test_database_queries.py# Verifies date range filters & caches
|
|
100
|
+
├── test_sanitizer.py # Validates redactions & blacklists
|
|
101
|
+
├── test_ai.py # Verifies prompts & HTTP client mocks
|
|
102
|
+
├── test_tui.py # Textual app lifecycle tests & modal simulations
|
|
103
|
+
├── test_formatter_rich.py # Tests CLI layouts & styling
|
|
104
|
+
├── test_insights.py # Asserts Focus Score arithmetic
|
|
105
|
+
└── test_integration.py # End-to-end flow checks
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
---
|
|
109
|
+
|
|
110
|
+
## 3. Chronological Ingestion Pipeline
|
|
111
|
+
|
|
112
|
+
Data moves through a multi-stage pipeline whenever you query a CLI command or open the TUI dashboard:
|
|
113
|
+
|
|
114
|
+
1. **Ingest History Files**:
|
|
115
|
+
* Reads target shell history files (`~/.zsh_history`, `~/.bash_history`).
|
|
116
|
+
* Normalizes timestamps, separates multiline command backslashes (`\`), and constructs a flat sequence of `Command` objects.
|
|
117
|
+
2. **Chunk Sessions**:
|
|
118
|
+
* Walks the command sequence chronologically.
|
|
119
|
+
* If the time gap between two commands exceeds **30 minutes**, a new session boundary is created.
|
|
120
|
+
3. **Map Projects**:
|
|
121
|
+
* Looks up the file directory where the command was executed.
|
|
122
|
+
* Scans upward to find the repository configuration root (`.git`, `.hg`, `.svn`).
|
|
123
|
+
* Normalizes the directory name to a human-readable title. If no project is resolved, maps the session to the `"Other"` category.
|
|
124
|
+
4. **Ingest Git Commits**:
|
|
125
|
+
* Runs local `git log` commands to collect commits pushed/committed within the active session boundaries.
|
|
126
|
+
* Cleans emojis and tags from commit logs to prevent formatting bugs.
|
|
127
|
+
5. **Sanitize Data locally**:
|
|
128
|
+
* Runs the credentials sanitizer.
|
|
129
|
+
* Drops blacklisted commands from AI processing (short-circuiting them to return `"Security/Authentication Operations"`).
|
|
130
|
+
* Redacts IPs, passwords, FQDNs, URLs, and secret environment variables.
|
|
131
|
+
6. **Save & Cache**:
|
|
132
|
+
* Writes the resulting objects to `~/.termstory/termstory.db`.
|
|
133
|
+
* Caches high-level Month and Date summary strings in `macro_summaries`.
|
|
134
|
+
7. **Render & Visualize**:
|
|
135
|
+
* Outputs the results to standard stdout (formatted via `Rich` tables) or launches the non-blocking `Textual` TUI.
|
|
136
|
+
|
|
137
|
+
---
|
|
138
|
+
|
|
139
|
+
## 4. Shell History Parsing Mechanics
|
|
140
|
+
|
|
141
|
+
The parsing engine in [parser.py](file:///Users/himanshuverma/Projects/termstory/termstory/parser.py) handles differences between shell formatting styles:
|
|
142
|
+
|
|
143
|
+
### Zsh History Extended Format
|
|
144
|
+
Zsh records commands in the format:
|
|
145
|
+
```
|
|
146
|
+
: <timestamp>:<duration>;<command>
|
|
147
|
+
```
|
|
148
|
+
* **Regex Extraction**: `^:\s*(\d+):(\d+);(.*)$` isolates the timestamp, elapsed duration, and command text.
|
|
149
|
+
* **Multiline Support**: If a command ends with `\`, the parser continues appending lines until the backslash pattern is broken, ensuring complete code blocks (such as complex Docker configurations or make scripts) are captured.
|
|
150
|
+
|
|
151
|
+
### Bash History Format
|
|
152
|
+
Standard Bash histories only write raw command strings sequentially. If `HISTTIMEFORMAT` is configured, Bash writes timestamp headers beforehand:
|
|
153
|
+
```
|
|
154
|
+
#1620000000
|
|
155
|
+
git commit -m "docs"
|
|
156
|
+
```
|
|
157
|
+
* **Header Matching**: The parser checks for lines matching `^#(\d{10})$`.
|
|
158
|
+
* **Missing Timestamp Heuristics**: If timestamps are missing entirely, the parser calculates them using a **Backward-and-Forward Fill Algorithm**:
|
|
159
|
+
1. Retrieve the file's last modified time (`mtime`) as a baseline reference.
|
|
160
|
+
2. Map timestamps backwards in 10-second decrements from `mtime` for all trailing commands.
|
|
161
|
+
3. If some lines have timestamp markers while others do not, the parser fills the gaps chronologically using linear 10-second increments between known points.
|
|
162
|
+
|
|
163
|
+
---
|
|
164
|
+
|
|
165
|
+
## 5. VCS Root Resolution & Project Name Humanization
|
|
166
|
+
|
|
167
|
+
To avoid naming logs after temporary folders, the resolver in [project.py](file:///Users/himanshuverma/Projects/termstory/termstory/project.py) uses a double-tiered identification strategy:
|
|
168
|
+
|
|
169
|
+
```
|
|
170
|
+
Working Directory (e.g. /home/dev/src/termstory/tests)
|
|
171
|
+
↓
|
|
172
|
+
Search upward for VCS Roots (.git, .hg, .svn)
|
|
173
|
+
↓
|
|
174
|
+
[Found Root] -> /home/dev/src/termstory
|
|
175
|
+
↓
|
|
176
|
+
Check config files (package.json, setup.py, Cargo.toml, etc.)
|
|
177
|
+
↓
|
|
178
|
+
[Found package.json name] -> "termstory-tui" -> Map to "TermStory"
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
### Disambiguation Maps
|
|
182
|
+
Common abbreviations and workspace folders are mapped to clean names:
|
|
183
|
+
* Empty or system-level actions (e.g. commands run in `~` or `/`) are mapped to `"Other"`.
|
|
184
|
+
* Name humanization rules clean up string casing, strip trailing hyphens, and convert system terms (e.g. mapping `infra-k8s` to `Infra K8s`).
|
|
185
|
+
|
|
186
|
+
---
|
|
187
|
+
|
|
188
|
+
## 6. Git Commit Correlation Pipeline
|
|
189
|
+
|
|
190
|
+
To map Git history to shell commands, the engine in [git_integration.py](file:///Users/himanshuverma/Projects/termstory/termstory/git_integration.py) performs these steps:
|
|
191
|
+
|
|
192
|
+
1. **Subprocess Calls**: Spawns a non-interactive shell command:
|
|
193
|
+
```bash
|
|
194
|
+
git log --all --since="<session_start>" --until="<session_end>" --format="%H|%ct|%s"
|
|
195
|
+
```
|
|
196
|
+
2. **Conventional Commit Cleaning**:
|
|
197
|
+
* Removes commit categorization prefixes (e.g. `feat(tui):` becomes `tui:`, `fix:` is stripped).
|
|
198
|
+
* Strips git emojis (e.g. `:bug:`, `:fire:`, `🚀`).
|
|
199
|
+
* Drops merge branch references and commits matching standard merge pull request messages.
|
|
200
|
+
3. **Commit Association**: Maps matching commits to the active session by checking if they fall within the session's duration window.
|
|
201
|
+
|
|
202
|
+
---
|
|
203
|
+
|
|
204
|
+
## 7. Database Internals & Schema Reference
|
|
205
|
+
|
|
206
|
+
The storage layer in [database.py](file:///Users/himanshuverma/Projects/termstory/termstory/database.py) uses SQLite.
|
|
207
|
+
|
|
208
|
+
### WAL Configuration
|
|
209
|
+
Upon initialization, the database sets Write-Ahead Logging (WAL) to prevent database locks when background threads query the LLM while the user interacts with the timeline:
|
|
210
|
+
```sql
|
|
211
|
+
PRAGMA journal_mode = WAL;
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
### Database Tables Schema
|
|
215
|
+
|
|
216
|
+
```sql
|
|
217
|
+
-- 1. Track workspaces
|
|
218
|
+
CREATE TABLE IF NOT EXISTS projects (
|
|
219
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
220
|
+
name TEXT NOT NULL UNIQUE,
|
|
221
|
+
path TEXT,
|
|
222
|
+
first_seen INTEGER,
|
|
223
|
+
last_seen INTEGER,
|
|
224
|
+
created_at INTEGER DEFAULT (strftime('%s', 'now'))
|
|
225
|
+
);
|
|
226
|
+
|
|
227
|
+
-- 2. Sessions chronological groupings
|
|
228
|
+
CREATE TABLE IF NOT EXISTS sessions (
|
|
229
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
230
|
+
start_time INTEGER NOT NULL,
|
|
231
|
+
end_time INTEGER NOT NULL,
|
|
232
|
+
duration_seconds INTEGER,
|
|
233
|
+
project_id INTEGER,
|
|
234
|
+
ai_summary TEXT, -- Cached session narrative
|
|
235
|
+
created_at INTEGER DEFAULT (strftime('%s', 'now')),
|
|
236
|
+
FOREIGN KEY(project_id) REFERENCES projects(id)
|
|
237
|
+
);
|
|
238
|
+
|
|
239
|
+
-- 3. Individual command logs
|
|
240
|
+
CREATE TABLE IF NOT EXISTS commands (
|
|
241
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
242
|
+
timestamp INTEGER NOT NULL,
|
|
243
|
+
command TEXT NOT NULL,
|
|
244
|
+
exit_code INTEGER,
|
|
245
|
+
session_id INTEGER,
|
|
246
|
+
project_id INTEGER,
|
|
247
|
+
created_at INTEGER DEFAULT (strftime('%s', 'now')),
|
|
248
|
+
FOREIGN KEY(session_id) REFERENCES sessions(id),
|
|
249
|
+
FOREIGN KEY(project_id) REFERENCES projects(id)
|
|
250
|
+
);
|
|
251
|
+
|
|
252
|
+
-- 4. Cleaned git commits
|
|
253
|
+
CREATE TABLE IF NOT EXISTS commits (
|
|
254
|
+
hash TEXT PRIMARY KEY,
|
|
255
|
+
timestamp INTEGER NOT NULL,
|
|
256
|
+
message TEXT NOT NULL,
|
|
257
|
+
cleaned_message TEXT NOT NULL,
|
|
258
|
+
project_id INTEGER,
|
|
259
|
+
created_at INTEGER DEFAULT (strftime('%s', 'now')),
|
|
260
|
+
FOREIGN KEY(project_id) REFERENCES projects(id)
|
|
261
|
+
);
|
|
262
|
+
|
|
263
|
+
-- 5. Timeframe summaries cache (for TUI navigation speed)
|
|
264
|
+
CREATE TABLE IF NOT EXISTS macro_summaries (
|
|
265
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
266
|
+
timeframe_id TEXT NOT NULL UNIQUE, -- e.g. "2026-06-03" or "June 2026"
|
|
267
|
+
type TEXT NOT NULL, -- "date" or "month"
|
|
268
|
+
summary TEXT NOT NULL,
|
|
269
|
+
created_at INTEGER DEFAULT (strftime('%s', 'now'))
|
|
270
|
+
);
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
---
|
|
274
|
+
|
|
275
|
+
## 8. Privacy Sanitizer Pipeline
|
|
276
|
+
|
|
277
|
+
The local sanitizer pipeline in [sanitizer.py](file:///Users/himanshuverma/Projects/termstory/termstory/sanitizer.py) ensures no sensitive tokens, credentials, or hostnames reach the LLM API.
|
|
278
|
+
|
|
279
|
+
### A. Blacklist Filters
|
|
280
|
+
If a command matches any of the following patterns, the entire session's AI request is aborted, and the database stores a fallback status message:
|
|
281
|
+
```python
|
|
282
|
+
BLACKLIST_PATTERNS = [
|
|
283
|
+
re.compile(r'\bvault\b', re.IGNORECASE),
|
|
284
|
+
re.compile(r'\baws\s+configure\b', re.IGNORECASE),
|
|
285
|
+
re.compile(r'\bgh\s+auth\b', re.IGNORECASE),
|
|
286
|
+
re.compile(r'\bkubectl\s+.*?\bcreate\s+secret\b', re.IGNORECASE)
|
|
287
|
+
]
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
### B. Regular Expression Masking Rules
|
|
291
|
+
|
|
292
|
+
| Parameter | Regex Match Rule | Replacement Target |
|
|
293
|
+
|---|---|---|
|
|
294
|
+
| **Private Keys** | `-----BEGIN [A-Z ]+ PRIVATE KEY-----.*?-----END...` | `[REDACTED_PRIVATE_KEY]` |
|
|
295
|
+
| **AWS API Keys** | `\b(?:AKIA\|ASIA)[A-Z0-9]{16}\b` | `[REDACTED_AWS_KEY]` |
|
|
296
|
+
| **Slack Tokens** | `\bxoxb-[0-9]{11,13}-[a-zA-Z0-9]{24}\b` | `[REDACTED_SLACK_TOKEN]` |
|
|
297
|
+
| **Bearer Tokens** | `\bbearer\s+([a-zA-Z0-9\-._~+/]+=*)\b` | `Bearer [REDACTED_TOKEN]` |
|
|
298
|
+
| **Exports** | `(export\s+[A-Za-z0-9_]+=)([^ ]+)` | `export KEY=[REDACTED]` |
|
|
299
|
+
| **Auth Flags** | `--password`, `-p`, `--token`, `--api-key` | `--password=[REDACTED]` |
|
|
300
|
+
| **IP Addresses** | `\b(?:\d{1,3}\.){3}\d{1,3}\b` | `[REDACTED_IP]` |
|
|
301
|
+
|
|
302
|
+
### C. FQDN Exclusions
|
|
303
|
+
The pipeline preserves file paths and configs by checking match extensions against a whitelist:
|
|
304
|
+
```python
|
|
305
|
+
FILE_EXTENSIONS = {
|
|
306
|
+
'py', 'json', 'db', 'sh', 'xml', 'yml', 'yaml', 'md', 'txt', 'c', 'cpp',
|
|
307
|
+
'h', 'go', 'java', 'js', 'ts', 'html', 'css', 'sqlite', 'sqlite3', 'rs'
|
|
308
|
+
}
|
|
309
|
+
```
|
|
310
|
+
If a matched string ends with an extension in this list (e.g. `config.json`), it is left untouched. Otherwise, hostnames are replaced with `[REDACTED_HOST]`.
|
|
311
|
+
|
|
312
|
+
---
|
|
313
|
+
|
|
314
|
+
## 9. Zero-Dependency LLM API Client
|
|
315
|
+
|
|
316
|
+
The communication module in [ai.py](file:///Users/himanshuverma/Projects/termstory/termstory/ai.py) connects to OpenAI-compatible endpoints using Python's native standard library:
|
|
317
|
+
|
|
318
|
+
* **Urllib Requester**: Employs `urllib.request.Request` to perform POST payloads, eliminating dependencies on libraries like `requests` or `openai-python`.
|
|
319
|
+
* **URL Normalization**: Normalizes base URL paths by stripping trailing slashes to prevent duplicate path slashes:
|
|
320
|
+
```python
|
|
321
|
+
endpoint = api_base_url.strip().rstrip('/')
|
|
322
|
+
if not endpoint.endswith('/chat/completions'):
|
|
323
|
+
endpoint = f"{endpoint}/chat/completions"
|
|
324
|
+
```
|
|
325
|
+
* **Empty Key Check**: Local instances (like Ollama running on `localhost:11434`) do not require authentication. The client checks if the API key is empty and skips adding the `Authorization: Bearer` header:
|
|
326
|
+
```python
|
|
327
|
+
if api_key and isinstance(api_key, str) and api_key.strip():
|
|
328
|
+
headers["Authorization"] = f"Bearer {api_key.strip()}"
|
|
329
|
+
```
|
|
330
|
+
|
|
331
|
+
---
|
|
332
|
+
|
|
333
|
+
## 10. Interactive TUI Dashboard Layout & Style System
|
|
334
|
+
|
|
335
|
+
The interactive dashboard is powered by the `Textual` framework:
|
|
336
|
+
|
|
337
|
+
```
|
|
338
|
+
┌────────────────────────────────────────────────────────────────────────────────────────┐
|
|
339
|
+
│ StatsHeader (Streak Count, Active Days, Cumulative Duration, Command Heatmap) │
|
|
340
|
+
├─────────────────────────────────────────┬──────────────────────────────────────────────┤
|
|
341
|
+
│ HistoryTree (Timeline Navigator) │ DetailsCanvas (Main Panel) │
|
|
342
|
+
│ - June 2026 │ - AI Timeframe summaries │
|
|
343
|
+
│ - Jun 03 (Wed) │ - Card breakdowns (Commits, Projects) │
|
|
344
|
+
│ - TermStory │ - Time Distribution charts │
|
|
345
|
+
│ - session 09:15-09:45 │ - Git Commit lists │
|
|
346
|
+
│ │ - Command Timelines with noise muted) │
|
|
347
|
+
└─────────────────────────────────────────┴──────────────────────────────────────────────┘
|
|
348
|
+
```
|
|
349
|
+
|
|
350
|
+
### CSS Layout Rules
|
|
351
|
+
The layout is defined in [tui.py](file:///Users/himanshuverma/Projects/termstory/termstory/tui.py):
|
|
352
|
+
* **Master Layout Grid**: Sets up a `2 x 2` grid:
|
|
353
|
+
```css
|
|
354
|
+
#master-layout {
|
|
355
|
+
layout: grid;
|
|
356
|
+
grid-size: 2 2;
|
|
357
|
+
grid-rows: 3 1fr;
|
|
358
|
+
grid-columns: 30% 70%;
|
|
359
|
+
height: 1fr;
|
|
360
|
+
grid-gutter: 0;
|
|
361
|
+
}
|
|
362
|
+
```
|
|
363
|
+
* **Stats Header**: Spans two columns (`column-span: 2`) at a fixed height of `3` rows, keeping a dark background (`#1a1a1e`) and a border separating it from the main workspace.
|
|
364
|
+
* **Explorer & Canvas Panels**: Set to scrollable height blocks with a dark background (`#121214`), separated by a thin vertical line (`border-right: solid #323238`).
|
|
365
|
+
|
|
366
|
+
### Navigation & Shortcuts Help Screen
|
|
367
|
+
Pressing `?` opens a centered modal help overlay containing keyboard shortcuts. It can be dismissed by pressing `Escape`, `q`, or clicking Close.
|
|
368
|
+
|
|
369
|
+
| Category | Key | Action |
|
|
370
|
+
|---|---|---|
|
|
371
|
+
| **Global Navigation** | `?` | Toggle Shortcuts Help Menu |
|
|
372
|
+
| | `/` | Open dynamic regex Search / Filter box |
|
|
373
|
+
| | `o` | Open AI Configuration Onboarding Screen |
|
|
374
|
+
| | `q` / `Esc` | Quit dashboard / Close active modal / Clear search filter |
|
|
375
|
+
| **Canvas Scrolling** | `Ctrl+Down` / `Ctrl+j` | Scroll details canvas down |
|
|
376
|
+
| | `Ctrl+Up` / `Ctrl+k` | Scroll details canvas up |
|
|
377
|
+
| | `Ctrl+PgDn` / `Ctrl+PgUp` | Scroll details canvas by half-page |
|
|
378
|
+
| **Timeline Explorer** | `j` / `k` (or arrows) | Navigate up and down the timeline tree nodes |
|
|
379
|
+
| | `Enter` / `Space` | Expand or collapse chronological tree groupings |
|
|
380
|
+
| **Onboarding Form** | `Ctrl+g` / `Ctrl+a` | Choose Groq / Choose OpenAI |
|
|
381
|
+
| | `Ctrl+l` / `Ctrl+c` | Choose Ollama / Choose Custom API |
|
|
382
|
+
| | `Ctrl+d` | Disable AI (strictly offline, local TUI heuristics only) |
|
|
383
|
+
|
|
384
|
+
### Robust Clipboard Copy System
|
|
385
|
+
* **Binding**: Pressing `c` copies the selected text in the details panel to the operating system's clipboard.
|
|
386
|
+
* **Mechanism**: To bypass restrictions where terminal emulators do not support or have disabled terminal clipboard escape codes (OSC 52), the TUI implements a dual-layered copy pipeline:
|
|
387
|
+
1. **OS-Level Subprocess**: It attempts to pipe the text directly to OS clipboard binaries (`pbcopy` on macOS, `xclip`/`xsel`/`wl-copy` on Linux, and `clip` on Windows).
|
|
388
|
+
2. **OSC 52 Fallback**: It executes Textual's default `copy_to_clipboard` method which issues ANSI escape sequences to the terminal, allowing support for SSH/remote sessions.
|
|
389
|
+
* **ANSI Stripping**: The copy engine automatically cleans raw ANSI styling codes from the selection to ensure only clean, plain text is copied.
|
|
390
|
+
|
|
391
|
+
### Background Workers
|
|
392
|
+
To prevent network requests from freezing the UI, TUI uses Textual's `@work` thread-based async decorators.
|
|
393
|
+
The app spawns background query tasks to process LLM request threads. Once completed, they update the `DetailsCanvas` view and the `HistoryTree` node labels.
|
|
394
|
+
|
|
395
|
+
---
|
|
396
|
+
|
|
397
|
+
## 11. AI Prompts & Narrative Design Rules
|
|
398
|
+
|
|
399
|
+
TermStory generates summaries using prompts designed to avoid corporate marketing slop and output high-density, CLI-styled dev logs.
|
|
400
|
+
|
|
401
|
+
### Prompt Content Rules
|
|
402
|
+
1. **High-Density Output**: Restructures the summary into a 3-line ASCII tree/tech bullet log mimicking terminal diagnostics rather than standard paragraph reviews.
|
|
403
|
+
2. **Technical Progression**: Sequentially tracks what was built first, what tooling/flow followed next, and the outcome/status of the session.
|
|
404
|
+
3. **No Fluff**: Strictly forbids generic filler lines ("Ultimately, the hard work paid off..."). Keeps it direct and technical.
|
|
405
|
+
4. **Developer Voice**: Employs active past-tense engineering verbs at the start of each log line (e.g. *wired up, refactored, hacked on, stabilized, shipped*).
|
|
406
|
+
|
|
407
|
+
### Prompt Templates
|
|
408
|
+
|
|
409
|
+
#### A. Session Summaries Prompt
|
|
410
|
+
```
|
|
411
|
+
Translate the developer's raw shell commands and Git commits into a high-density, CLI-styled terminal log of their work session.
|
|
412
|
+
|
|
413
|
+
YOUR CORE GOAL:
|
|
414
|
+
Generate a 3-line bulleted dev log. It must resemble a clean, tech-dense terminal audit output using ASCII connection lines or tech symbols.
|
|
415
|
+
|
|
416
|
+
Choose ONE of the following formats to return, matching the inputs:
|
|
417
|
+
|
|
418
|
+
Format Option A (ASCII branch log style):
|
|
419
|
+
[💻 Dev Log]
|
|
420
|
+
├─ 🔨 Built: <short, punchy action phrase of what was built or coded, using tech keywords>
|
|
421
|
+
├─ 🔧 Flow: <brief sequence of tools used, tests run, or configurations edited>
|
|
422
|
+
└─ 🚀 Result: <final milestone shipped, fixed, or pushed>
|
|
423
|
+
|
|
424
|
+
Format Option B (Tech bullet list style):
|
|
425
|
+
[🤖 Codebase Pulse]
|
|
426
|
+
• Hacked: <what was designed, refactored, or debugged>
|
|
427
|
+
• Tooling: <commands run, docker setups, or libraries configured>
|
|
428
|
+
• Outcome: <what was successfully verified, resolved, or shipped>
|
|
429
|
+
|
|
430
|
+
Choose either Option A or Option B at random or based on the inputs to provide variation, but always output EXACTLY the selected format.
|
|
431
|
+
Never output any paragraphs of text, conversational filler, markdown formatting, or surrounding quotes. Only return the raw 4 lines of console text.
|
|
432
|
+
|
|
433
|
+
STYLE & TONE RULES:
|
|
434
|
+
1. NO MARKETING FLUFF: Never write paragraphs like 'Ultimately, the hard work paid off...'. Keep it purely developer-centric and density-focused.
|
|
435
|
+
2. START WITH ACTION VERBS: Each bullet line must start directly with an active, past-tense engineering verb (e.g., 'wired up', 'refactored', 'debugged', 'spun up', 'implemented').
|
|
436
|
+
3. Keep each line extremely concise, informative, and technical.
|
|
437
|
+
|
|
438
|
+
Input Data to Summarize:
|
|
439
|
+
Project: {project_name}
|
|
440
|
+
Commands Executed:
|
|
441
|
+
{commands_block}
|
|
442
|
+
{commits_block}
|
|
443
|
+
|
|
444
|
+
Output format: Return ONLY the raw, polished console text block. No markdown formatting, no conversational filler, and no surrounding quotes.
|
|
445
|
+
```
|
|
446
|
+
|
|
447
|
+
#### B. Timeframe/Executive Review Prompt
|
|
448
|
+
```
|
|
449
|
+
Write a highly-personalized, modern engineering review of the developer's work over this entire period based on their commits, session summaries, and tooling stats.
|
|
450
|
+
|
|
451
|
+
YOUR CORE GOAL:
|
|
452
|
+
Generate a high-density, CLI-styled audit review of the timeframe. It must resemble terminal diagnostic output using ASCII connection lines, matching this exact structure:
|
|
453
|
+
|
|
454
|
+
✨ [⚡ Timeframe Audit]
|
|
455
|
+
├─ 📂 <Project A Name> [XX%]
|
|
456
|
+
├─ 📂 <Project B Name> [XX%]
|
|
457
|
+
└─ 📂 Misc / Sys Config [XX%]
|
|
458
|
+
|
|
459
|
+
RULES FOR GENERATION:
|
|
460
|
+
1. Extract the projects and their percentage distributions from the input context (PROJECTS DISTRIBUTION).
|
|
461
|
+
2. List the projects in descending order of percentage.
|
|
462
|
+
3. Truncate any projects with less than 5% share or named 'Other', and group their combined percentages into a single final line: '└─ 📂 Misc / Sys Config [XX%]'.
|
|
463
|
+
4. Use the branch characters correctly: '├─ 📂' for all projects except the last one, which must use '└─ 📂'.
|
|
464
|
+
5. Keep the alignment neat.
|
|
465
|
+
6. Do not output any paragraphs, explanations, conversational filler, markdown formatting, or surrounding quotes. Only return the raw lines of console text.
|
|
466
|
+
|
|
467
|
+
Developer Work Log Context:
|
|
468
|
+
{stats_summary}
|
|
469
|
+
|
|
470
|
+
Output format: Return ONLY the raw, polished console text block. No markdown formatting, no conversational filler, and no surrounding quotes.
|
|
471
|
+
```
|
|
472
|
+
|
|
473
|
+
---
|
|
474
|
+
|
|
475
|
+
## 12. CLI Command Reference
|
|
476
|
+
|
|
477
|
+
### `termstory` / `termstory today`
|
|
478
|
+
Queries work done today.
|
|
479
|
+
* `termstory` — Display today's timeline grouped by project.
|
|
480
|
+
* `termstory today --detailed` — Mute the filters and dump the raw list of all commands in today's sessions with exact timestamps.
|
|
481
|
+
* `termstory today --compare` — Display today's summary side-by-side with yesterday's work log.
|
|
482
|
+
* `termstory today --stats` — Show a formatted table breaking down command frequencies by category (Git, Docker, Package Managers, Editors, Navigations).
|
|
483
|
+
|
|
484
|
+
### `termstory search <query>`
|
|
485
|
+
Searches your commands, commits, and project names.
|
|
486
|
+
* `termstory search docker` — Find all Docker sessions, collapsed by day per project.
|
|
487
|
+
* `termstory search docker --project huge` — Filter results to projects matching "huge".
|
|
488
|
+
* `termstory search docker --since 2026-05-01` — Return matches since the specified date.
|
|
489
|
+
* `termstory search docker --detailed` — Show timestamps and raw executed command logs for the matches.
|
|
490
|
+
|
|
491
|
+
### `termstory week`
|
|
492
|
+
Prints a weekly summary.
|
|
493
|
+
* `termstory week` — Display work report for the current week.
|
|
494
|
+
* `termstory week --last` — Display work report for last week.
|
|
495
|
+
* `termstory week --project hugegraph` — Filter weekly summary to the specific project.
|
|
496
|
+
|
|
497
|
+
### `termstory month`
|
|
498
|
+
Prints a monthly summary.
|
|
499
|
+
* `termstory month` — Display summary for the current month.
|
|
500
|
+
* `termstory month "May 2026"` — Query data for a specific historical month.
|
|
501
|
+
* `termstory month --last` — Query data for the previous month.
|
|
502
|
+
|
|
503
|
+
### `termstory project <name>`
|
|
504
|
+
Prints a 30-day deep dive for a single project.
|
|
505
|
+
* `termstory project hugegraph` — Display dates and accomplishments/memories.
|
|
506
|
+
* `termstory project hugegraph --files` — List files edited within the project workspace, sorted by frequency.
|
|
507
|
+
* `termstory project hugegraph --stats` — Display command stats categories for the project.
|
|
508
|
+
|
|
509
|
+
### `termstory projects`
|
|
510
|
+
Lists all tracked workspaces.
|
|
511
|
+
* `termstory projects --sort time` — Sort by cumulative hours (default).
|
|
512
|
+
* `termstory projects --sort recent` — Sort by date of last activity.
|
|
513
|
+
* `termstory projects --sort name` — Sort alphabetically.
|
|
514
|
+
|
|
515
|
+
### `termstory insights`
|
|
516
|
+
Analyzes patterns.
|
|
517
|
+
* `termstory insights --days 90` — Evaluates focus scores, time of day/week distributions, and tool breakdowns for the last 90 days.
|
|
518
|
+
|
|
519
|
+
### `termstory ui`
|
|
520
|
+
Launches the Textual dashboard.
|
|
521
|
+
* `termstory ui` — Launches TUI displaying the last 90 days (default).
|
|
522
|
+
* `termstory ui --days 30` — Limit history timeline to the last 30 days.
|
|
523
|
+
* `termstory ui --all` — Build timeline explorer for all recorded database sessions.
|
|
524
|
+
|
|
525
|
+
### `termstory config`
|
|
526
|
+
* `termstory config list` — Print all current settings, masking API keys.
|
|
527
|
+
* `termstory config get active_provider` — Retrieve a configuration value.
|
|
528
|
+
* `termstory config set active_provider ollama` — Write a configuration parameter.
|
|
529
|
+
|
|
530
|
+
### Date Override Env
|
|
531
|
+
You can query historical dates directly:
|
|
532
|
+
* `termstory 2026-05-15` — Summary for May 15th, 2026.
|
|
533
|
+
* `termstory --date 2026-05-15 week` — Weekly report for the week containing May 15th, 2026.
|
|
534
|
+
|
|
535
|
+
---
|
|
536
|
+
|
|
537
|
+
## 13. Configuration Reference (`config.json`)
|
|
538
|
+
|
|
539
|
+
The config file is located at `~/.termstory/config.json`. Below is the complete structured representation of the settings:
|
|
540
|
+
|
|
541
|
+
```json
|
|
542
|
+
{
|
|
543
|
+
"ai_enabled": false,
|
|
544
|
+
"active_provider": "disabled",
|
|
545
|
+
"has_seen_onboarding": false,
|
|
546
|
+
"providers": {
|
|
547
|
+
"groq": {
|
|
548
|
+
"api_key": "gsk_...",
|
|
549
|
+
"api_base_url": "https://api.groq.com/openai/v1",
|
|
550
|
+
"model_name": "llama-3.1-8b-instant"
|
|
551
|
+
},
|
|
552
|
+
"openai": {
|
|
553
|
+
"api_key": "sk-proj-...",
|
|
554
|
+
"api_base_url": "https://api.openai.com/v1",
|
|
555
|
+
"model_name": "gpt-4o-mini"
|
|
556
|
+
},
|
|
557
|
+
"ollama": {
|
|
558
|
+
"api_key": "",
|
|
559
|
+
"api_base_url": "http://localhost:11434/v1",
|
|
560
|
+
"model_name": "llama3"
|
|
561
|
+
}
|
|
562
|
+
}
|
|
563
|
+
}
|
|
564
|
+
```
|
|
565
|
+
|
|
566
|
+
### Configuration Dot Paths
|
|
567
|
+
You can query and edit settings using dot notation paths via `termstory config set <path> <value>`.
|
|
568
|
+
|
|
569
|
+
Supported paths:
|
|
570
|
+
* `ai_enabled` (boolean: `true`/`false`)
|
|
571
|
+
* `active_provider` (string: `"groq"`, `"openai"`, `"ollama"`, `"disabled"`)
|
|
572
|
+
* `has_seen_onboarding` (boolean: `true`/`false`)
|
|
573
|
+
* `providers.groq.api_key` (string)
|
|
574
|
+
* `providers.groq.api_base_url` (string)
|
|
575
|
+
* `providers.groq.model_name` (string)
|
|
576
|
+
* `providers.openai.api_key` (string)
|
|
577
|
+
* `providers.openai.api_base_url` (string)
|
|
578
|
+
* `providers.openai.model_name` (string)
|
|
579
|
+
* `providers.ollama.api_key` (string)
|
|
580
|
+
* `providers.ollama.api_base_url` (string)
|
|
581
|
+
* `providers.ollama.model_name` (string)
|
|
582
|
+
|
|
583
|
+
---
|
|
584
|
+
|
|
585
|
+
## 14. Developer Verification & Testing Suite
|
|
586
|
+
|
|
587
|
+
TermStory uses `pytest` for unit and integration testing.
|
|
588
|
+
|
|
589
|
+
### Running Tests
|
|
590
|
+
Run the following command from the project root:
|
|
591
|
+
```bash
|
|
592
|
+
python3 -m pytest tests/
|
|
593
|
+
```
|
|
594
|
+
|
|
595
|
+
### Test Directory Breakdown
|
|
596
|
+
|
|
597
|
+
* `test_parser.py`: Verifies Zsh history format matching, bash modifications, and spacing heuristics.
|
|
598
|
+
* `test_session.py`: Tests the 30-minute grouping calculations, session boundaries, and duration logic.
|
|
599
|
+
* `test_project.py`: Asserts project path resolution, Git folder matching, file parsers, and "Other" mappings.
|
|
600
|
+
* `test_git_integration.py`: Mocks Git command outputs and verifies message cleaning.
|
|
601
|
+
* `test_database.py` & `test_database_queries.py`: Tests connection PRAGMAs, SQL queries, inserts, and caches.
|
|
602
|
+
* `test_sanitizer.py`: Verifies credential, token, IP, and hostname redaction rules.
|
|
603
|
+
* `test_ai.py`: Validates the custom `urllib.request` payload construction and mocking scenarios.
|
|
604
|
+
* `test_tui.py`: Spawns Textual test runners to simulate keyboard presses, help modals, onboarding flow screens, and tree navigation updates.
|
|
605
|
+
* `test_formatter_rich.py`: Asserts console command output rendering.
|
|
606
|
+
|
|
607
|
+
---
|
|
608
|
+
|
|
609
|
+
## 15. Troubleshooting & Personal Customization Hacks
|
|
610
|
+
|
|
611
|
+
### A. Reset to a Clean Slate
|
|
612
|
+
To reset the tool's history, cached summaries, and configuration, remove the local files:
|
|
613
|
+
```bash
|
|
614
|
+
rm -rf ~/.termstory/
|
|
615
|
+
```
|
|
616
|
+
The next command execution or TUI launch will initialize a new database and display the onboarding screen.
|
|
617
|
+
|
|
618
|
+
### B. Manually Trigger History Sync
|
|
619
|
+
If new command lines or commits are not showing up, run:
|
|
620
|
+
```bash
|
|
621
|
+
python3 -m termstory.cli today --detailed
|
|
622
|
+
```
|
|
623
|
+
This forces a file read and updates the local SQLite tables.
|
|
624
|
+
|
|
625
|
+
### C. Enable Local AI (Ollama Setup)
|
|
626
|
+
1. Ensure Ollama is running locally:
|
|
627
|
+
```bash
|
|
628
|
+
ollama run llama3
|
|
629
|
+
```
|
|
630
|
+
2. Open the TUI:
|
|
631
|
+
```bash
|
|
632
|
+
termstory ui
|
|
633
|
+
```
|
|
634
|
+
3. Press `o` to open the AI configuration panel.
|
|
635
|
+
4. Select Ollama (press `Ctrl+L`).
|
|
636
|
+
5. Set the model name to `llama3` and save. The tool will begin querying the local instance for summaries.
|