llmess 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.
@@ -0,0 +1,50 @@
1
+ name: Publish to PyPI
2
+
3
+ on:
4
+ release:
5
+ types: [published]
6
+
7
+ jobs:
8
+ build:
9
+ name: Build distribution
10
+ runs-on: ubuntu-latest
11
+ steps:
12
+ - uses: actions/checkout@v6
13
+ with:
14
+ persist-credentials: false
15
+
16
+ - name: Set up Python
17
+ uses: actions/setup-python@v6
18
+ with:
19
+ python-version: "3.x"
20
+
21
+ - name: Install build dependencies
22
+ run: python3 -m pip install build --user
23
+
24
+ - name: Build package
25
+ run: python3 -m build
26
+
27
+ - name: Store distribution packages
28
+ uses: actions/upload-artifact@v5
29
+ with:
30
+ name: python-package-distributions
31
+ path: dist/
32
+
33
+ publish:
34
+ name: Publish to PyPI
35
+ needs: build
36
+ runs-on: ubuntu-latest
37
+ environment:
38
+ name: pypi
39
+ url: https://pypi.org/p/llmess
40
+ permissions:
41
+ id-token: write # Required for OIDC trusted publishing
42
+ steps:
43
+ - name: Download distribution packages
44
+ uses: actions/download-artifact@v6
45
+ with:
46
+ name: python-package-distributions
47
+ path: dist/
48
+
49
+ - name: Publish to PyPI
50
+ uses: pypa/gh-action-pypi-publish@release/v1
@@ -0,0 +1,50 @@
1
+ name: Tests
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+ branches: [main]
8
+
9
+ jobs:
10
+ test:
11
+ runs-on: ubuntu-latest
12
+ strategy:
13
+ matrix:
14
+ python-version: ["3.8", "3.9", "3.10", "3.11", "3.12"]
15
+ steps:
16
+ - uses: actions/checkout@v6
17
+ with:
18
+ persist-credentials: false
19
+
20
+ - name: Set up Python ${{ matrix.python-version }}
21
+ uses: actions/setup-python@v6
22
+ with:
23
+ python-version: ${{ matrix.python-version }}
24
+
25
+ - name: Install dependencies
26
+ run: |
27
+ python -m pip install --upgrade pip
28
+ pip install pytest
29
+ pip install -e .
30
+
31
+ - name: Run tests
32
+ run: pytest tests/ -v
33
+
34
+ lint:
35
+ runs-on: ubuntu-latest
36
+ steps:
37
+ - uses: actions/checkout@v6
38
+ with:
39
+ persist-credentials: false
40
+
41
+ - name: Set up Python
42
+ uses: actions/setup-python@v6
43
+ with:
44
+ python-version: "3.12"
45
+
46
+ - name: Install ruff
47
+ run: pip install ruff
48
+
49
+ - name: Run ruff
50
+ run: ruff check src/ tests/
@@ -0,0 +1,34 @@
1
+ # Byte-compiled / optimized / DLL files
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+ *.so
6
+
7
+ # Distribution / packaging
8
+ .Python
9
+ build/
10
+ dist/
11
+ *.egg-info/
12
+ .eggs/
13
+ *.egg
14
+
15
+ # Virtual environments
16
+ .venv/
17
+ venv/
18
+ ENV/
19
+
20
+ # Testing
21
+ .pytest_cache/
22
+ .coverage
23
+ htmlcov/
24
+
25
+ # Editor files
26
+ *.swp
27
+ *.swo
28
+ *~
29
+ .idea/
30
+ .vscode/
31
+
32
+ # OS files
33
+ .DS_Store
34
+ Thumbs.db
llmess-0.1.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 tgies
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.
llmess-0.1.0/PKG-INFO ADDED
@@ -0,0 +1,205 @@
1
+ Metadata-Version: 2.4
2
+ Name: llmess
3
+ Version: 0.1.0
4
+ Summary: A less pager that uses LLMs to hallucinate infinite file continuations
5
+ Project-URL: Homepage, https://github.com/tgies/llmess
6
+ Project-URL: Repository, https://github.com/tgies/llmess
7
+ Author: tgies
8
+ License-Expression: MIT
9
+ License-File: LICENSE
10
+ Keywords: cli,humor,less,llm,pager
11
+ Classifier: Development Status :: 4 - Beta
12
+ Classifier: Environment :: Console
13
+ Classifier: Environment :: Console :: Curses
14
+ Classifier: Intended Audience :: Developers
15
+ Classifier: License :: OSI Approved :: MIT License
16
+ Classifier: Operating System :: POSIX
17
+ Classifier: Programming Language :: Python :: 3
18
+ Classifier: Programming Language :: Python :: 3.8
19
+ Classifier: Programming Language :: Python :: 3.9
20
+ Classifier: Programming Language :: Python :: 3.10
21
+ Classifier: Programming Language :: Python :: 3.11
22
+ Classifier: Programming Language :: Python :: 3.12
23
+ Classifier: Topic :: Games/Entertainment
24
+ Classifier: Topic :: Text Processing
25
+ Requires-Python: >=3.8
26
+ Description-Content-Type: text/markdown
27
+
28
+ # llmess
29
+
30
+ Some files end too early. Some files don't contain what you're looking for.
31
+
32
+ `llmess` is a `less` pager that addresses both issues:
33
+
34
+ - When you scroll past the end of a file, an LLM generates more content.
35
+ - When you search for a term that doesn't exist, the LLM generates content containing it.
36
+
37
+ Works with any model supported by the [`llm`](https://llm.datasette.io/) CLI.
38
+
39
+ ## Installation
40
+
41
+ ### Prerequisites
42
+
43
+ You need the [`llm`](https://llm.datasette.io/) CLI tool installed and configured:
44
+
45
+ ```bash
46
+ # Install llm
47
+ pipx install llm
48
+
49
+ # Install plugins for your preferred provider
50
+ llm install llm-openrouter # or llm-claude, llm-ollama, etc.
51
+
52
+ # Configure API keys and default model
53
+ llm keys set openrouter
54
+ llm models default openrouter/meta-llama/llama-3.1-405b
55
+ ```
56
+
57
+ ### Install llmess
58
+
59
+ ```bash
60
+ pipx install llmess
61
+ ```
62
+
63
+ Or with pip:
64
+
65
+ ```bash
66
+ pip install llmess
67
+ ```
68
+
69
+ > **Note**: llmess calls `llm` via subprocess, so it uses whatever `llm` is on your PATH. Your plugins and configuration are preserved.
70
+
71
+ ## Usage
72
+
73
+ ```bash
74
+ llmess myfile.txt # View a file
75
+ llmess -m gpt-4o myfile.txt # Use a specific model
76
+ llmess -B myfile.txt # Base mode: no system prompt
77
+ cat file.txt | llmess # Read from stdin
78
+ ```
79
+
80
+ ### Options
81
+
82
+ | Flag | Description |
83
+ |------|-------------|
84
+ | `-m`, `--model` | LLM model to use (default: your `llm` default) |
85
+ | `-s`, `--system` | System prompt (default: instruct prompt) |
86
+ | `-B`, `--base` | Base model mode: no system prompt |
87
+ | `-S`, `--stealth` | Mimic `less` appearance exactly-ish probably |
88
+ | `-T`, `--max-tokens N` | Max tokens to generate per LLM call |
89
+ | `-C`, `--context CHARS` | Characters of context to send to LLM (default: 2000) |
90
+ | `-o`, `--option KEY VALUE` | Model option to pass to llm (can be repeated) |
91
+ | `-P`, `--prefetch [N]` | Prefetch N screens ahead in background (off by default; 2 if flag given without N) |
92
+ | `--real-lines N` | Show first N real lines, then generate continuations |
93
+ | `--real-screen` | Show first screenful of real content, then generate |
94
+ | `--install-prank` | Output shell function to wrap `less` with llmess |
95
+ | `-V`, `--version` | Show version |
96
+
97
+ ### Environment Variables
98
+
99
+ | Variable | Description |
100
+ |----------|-------------|
101
+ | `LLMESS` | Default CLI flags (like `LESS` for less) |
102
+ | `LLMESS_MODEL` | Default model |
103
+ | `LLMESS_OPTIONS` | Default model options (comma-separated `key=value` pairs) |
104
+
105
+ ```bash
106
+ # In ~/.bashrc or ~/.zshrc
107
+ export LLMESS="-S -P" # stealth + prefetch by default
108
+ export LLMESS_MODEL="openrouter/meta-llama/llama-3.1-405b"
109
+ ```
110
+
111
+ Priority: CLI flags > `LLMESS` > `LLMESS_MODEL`/`LLMESS_OPTIONS` > built-in defaults.
112
+
113
+ ## Controls
114
+
115
+ | Key | Action |
116
+ |-----|--------|
117
+ | ↑ / k | Scroll up one line |
118
+ | ↓ / j | Scroll down one line |
119
+ | Page Up / b | Scroll up one page |
120
+ | Page Down / f / Space | Scroll down one page |
121
+ | g | Go to top |
122
+ | G | Go to bottom |
123
+ | / | Search forward |
124
+ | n | Next match |
125
+ | N | Previous match |
126
+ | Esc | Clear search |
127
+ | s | Save to file |
128
+ | q | Quit |
129
+
130
+ When you reach the bottom, scrolling down triggers LLM generation.
131
+
132
+ ## Search
133
+
134
+ Press `/` to search. Matches are highlighted.
135
+
136
+ If the term isn't found, llmess generates content containing it:
137
+
138
+ ```bash
139
+ echo "Hello world" | llmess
140
+ # Press /password<Enter>
141
+ # → Generates content containing "password", jumps to match
142
+ ```
143
+
144
+ This requires a system prompt (the default). With `-B` (base mode), search behaves normally.
145
+
146
+ ## Base Models vs. Instruct Models
147
+
148
+ By default, llmess sends a system prompt instructing the model to continue text without commentary. This works well with instruct models and is ignored by base models.
149
+
150
+ **Base models** continue text naturally. Use `-B` to skip the system prompt:
151
+
152
+ ```bash
153
+ llmess -B -m openrouter/meta-llama/llama-3.1-405b myfile.txt
154
+ ```
155
+
156
+ Search-triggered generation is not available with base models since they don't follow instructions.
157
+
158
+ **Instruct models** work out of the box. Use `-s "custom prompt"` to override the default:
159
+
160
+ ```bash
161
+ llmess -s "Continue this text exactly. No commentary." myfile.txt
162
+ ```
163
+
164
+ Any model supported by `llm` works, including local models via Ollama.
165
+
166
+ ## Modes
167
+
168
+ ### Stealth Mode
169
+
170
+ With `-S`, llmess mimics the appearance of `less`:
171
+ - Status bar shows `filename lines 1-24 50%` format
172
+ - No `[GENERATING...]` indicator
173
+ - Shows `(END)` at bottom
174
+
175
+ ### Prefetch Mode
176
+
177
+ With `-P`, llmess generates content ahead of where you're reading:
178
+
179
+ ```bash
180
+ llmess -P file.txt # Prefetch 2 screens ahead
181
+ llmess -P 5 file.txt # Prefetch 5 screens ahead
182
+ ```
183
+
184
+ ### Real-Then-Fake Mode
185
+
186
+ Show real file content first, then generate continuations:
187
+
188
+ ```bash
189
+ llmess --real-lines 50 ~/.bashrc # First 50 lines are real
190
+ llmess --real-screen config.yaml # First screenful is real
191
+ ```
192
+
193
+ ## Prank Installation
194
+
195
+ ```bash
196
+ llmess --install-prank
197
+ ```
198
+
199
+ Outputs a shell function that wraps `less` with llmess. Add it to the target's shell config.
200
+
201
+ The wrapper uses stealth mode, shows real content first, prefetches in background, and falls back to real `less` for piped output.
202
+
203
+ ## License
204
+
205
+ MIT
llmess-0.1.0/README.md ADDED
@@ -0,0 +1,178 @@
1
+ # llmess
2
+
3
+ Some files end too early. Some files don't contain what you're looking for.
4
+
5
+ `llmess` is a `less` pager that addresses both issues:
6
+
7
+ - When you scroll past the end of a file, an LLM generates more content.
8
+ - When you search for a term that doesn't exist, the LLM generates content containing it.
9
+
10
+ Works with any model supported by the [`llm`](https://llm.datasette.io/) CLI.
11
+
12
+ ## Installation
13
+
14
+ ### Prerequisites
15
+
16
+ You need the [`llm`](https://llm.datasette.io/) CLI tool installed and configured:
17
+
18
+ ```bash
19
+ # Install llm
20
+ pipx install llm
21
+
22
+ # Install plugins for your preferred provider
23
+ llm install llm-openrouter # or llm-claude, llm-ollama, etc.
24
+
25
+ # Configure API keys and default model
26
+ llm keys set openrouter
27
+ llm models default openrouter/meta-llama/llama-3.1-405b
28
+ ```
29
+
30
+ ### Install llmess
31
+
32
+ ```bash
33
+ pipx install llmess
34
+ ```
35
+
36
+ Or with pip:
37
+
38
+ ```bash
39
+ pip install llmess
40
+ ```
41
+
42
+ > **Note**: llmess calls `llm` via subprocess, so it uses whatever `llm` is on your PATH. Your plugins and configuration are preserved.
43
+
44
+ ## Usage
45
+
46
+ ```bash
47
+ llmess myfile.txt # View a file
48
+ llmess -m gpt-4o myfile.txt # Use a specific model
49
+ llmess -B myfile.txt # Base mode: no system prompt
50
+ cat file.txt | llmess # Read from stdin
51
+ ```
52
+
53
+ ### Options
54
+
55
+ | Flag | Description |
56
+ |------|-------------|
57
+ | `-m`, `--model` | LLM model to use (default: your `llm` default) |
58
+ | `-s`, `--system` | System prompt (default: instruct prompt) |
59
+ | `-B`, `--base` | Base model mode: no system prompt |
60
+ | `-S`, `--stealth` | Mimic `less` appearance exactly-ish probably |
61
+ | `-T`, `--max-tokens N` | Max tokens to generate per LLM call |
62
+ | `-C`, `--context CHARS` | Characters of context to send to LLM (default: 2000) |
63
+ | `-o`, `--option KEY VALUE` | Model option to pass to llm (can be repeated) |
64
+ | `-P`, `--prefetch [N]` | Prefetch N screens ahead in background (off by default; 2 if flag given without N) |
65
+ | `--real-lines N` | Show first N real lines, then generate continuations |
66
+ | `--real-screen` | Show first screenful of real content, then generate |
67
+ | `--install-prank` | Output shell function to wrap `less` with llmess |
68
+ | `-V`, `--version` | Show version |
69
+
70
+ ### Environment Variables
71
+
72
+ | Variable | Description |
73
+ |----------|-------------|
74
+ | `LLMESS` | Default CLI flags (like `LESS` for less) |
75
+ | `LLMESS_MODEL` | Default model |
76
+ | `LLMESS_OPTIONS` | Default model options (comma-separated `key=value` pairs) |
77
+
78
+ ```bash
79
+ # In ~/.bashrc or ~/.zshrc
80
+ export LLMESS="-S -P" # stealth + prefetch by default
81
+ export LLMESS_MODEL="openrouter/meta-llama/llama-3.1-405b"
82
+ ```
83
+
84
+ Priority: CLI flags > `LLMESS` > `LLMESS_MODEL`/`LLMESS_OPTIONS` > built-in defaults.
85
+
86
+ ## Controls
87
+
88
+ | Key | Action |
89
+ |-----|--------|
90
+ | ↑ / k | Scroll up one line |
91
+ | ↓ / j | Scroll down one line |
92
+ | Page Up / b | Scroll up one page |
93
+ | Page Down / f / Space | Scroll down one page |
94
+ | g | Go to top |
95
+ | G | Go to bottom |
96
+ | / | Search forward |
97
+ | n | Next match |
98
+ | N | Previous match |
99
+ | Esc | Clear search |
100
+ | s | Save to file |
101
+ | q | Quit |
102
+
103
+ When you reach the bottom, scrolling down triggers LLM generation.
104
+
105
+ ## Search
106
+
107
+ Press `/` to search. Matches are highlighted.
108
+
109
+ If the term isn't found, llmess generates content containing it:
110
+
111
+ ```bash
112
+ echo "Hello world" | llmess
113
+ # Press /password<Enter>
114
+ # → Generates content containing "password", jumps to match
115
+ ```
116
+
117
+ This requires a system prompt (the default). With `-B` (base mode), search behaves normally.
118
+
119
+ ## Base Models vs. Instruct Models
120
+
121
+ By default, llmess sends a system prompt instructing the model to continue text without commentary. This works well with instruct models and is ignored by base models.
122
+
123
+ **Base models** continue text naturally. Use `-B` to skip the system prompt:
124
+
125
+ ```bash
126
+ llmess -B -m openrouter/meta-llama/llama-3.1-405b myfile.txt
127
+ ```
128
+
129
+ Search-triggered generation is not available with base models since they don't follow instructions.
130
+
131
+ **Instruct models** work out of the box. Use `-s "custom prompt"` to override the default:
132
+
133
+ ```bash
134
+ llmess -s "Continue this text exactly. No commentary." myfile.txt
135
+ ```
136
+
137
+ Any model supported by `llm` works, including local models via Ollama.
138
+
139
+ ## Modes
140
+
141
+ ### Stealth Mode
142
+
143
+ With `-S`, llmess mimics the appearance of `less`:
144
+ - Status bar shows `filename lines 1-24 50%` format
145
+ - No `[GENERATING...]` indicator
146
+ - Shows `(END)` at bottom
147
+
148
+ ### Prefetch Mode
149
+
150
+ With `-P`, llmess generates content ahead of where you're reading:
151
+
152
+ ```bash
153
+ llmess -P file.txt # Prefetch 2 screens ahead
154
+ llmess -P 5 file.txt # Prefetch 5 screens ahead
155
+ ```
156
+
157
+ ### Real-Then-Fake Mode
158
+
159
+ Show real file content first, then generate continuations:
160
+
161
+ ```bash
162
+ llmess --real-lines 50 ~/.bashrc # First 50 lines are real
163
+ llmess --real-screen config.yaml # First screenful is real
164
+ ```
165
+
166
+ ## Prank Installation
167
+
168
+ ```bash
169
+ llmess --install-prank
170
+ ```
171
+
172
+ Outputs a shell function that wraps `less` with llmess. Add it to the target's shell config.
173
+
174
+ The wrapper uses stealth mode, shows real content first, prefetches in background, and falls back to real `less` for piped output.
175
+
176
+ ## License
177
+
178
+ MIT
@@ -0,0 +1,56 @@
1
+ [build-system]
2
+ requires = ["hatchling"]
3
+ build-backend = "hatchling.build"
4
+
5
+ [project]
6
+ name = "llmess"
7
+ version = "0.1.0"
8
+ description = "A less pager that uses LLMs to hallucinate infinite file continuations"
9
+ readme = "README.md"
10
+ license = "MIT"
11
+ requires-python = ">=3.8"
12
+ authors = [
13
+ { name = "tgies" }
14
+ ]
15
+ keywords = ["llm", "pager", "less", "cli", "humor"]
16
+ classifiers = [
17
+ "Development Status :: 4 - Beta",
18
+ "Environment :: Console",
19
+ "Environment :: Console :: Curses",
20
+ "Intended Audience :: Developers",
21
+ "License :: OSI Approved :: MIT License",
22
+ "Operating System :: POSIX",
23
+ "Programming Language :: Python :: 3",
24
+ "Programming Language :: Python :: 3.8",
25
+ "Programming Language :: Python :: 3.9",
26
+ "Programming Language :: Python :: 3.10",
27
+ "Programming Language :: Python :: 3.11",
28
+ "Programming Language :: Python :: 3.12",
29
+ "Topic :: Text Processing",
30
+ "Topic :: Games/Entertainment",
31
+ ]
32
+ dependencies = [
33
+ # Note: llm is NOT listed here intentionally.
34
+ # llmess calls llm via subprocess and expects users to have it
35
+ # installed at user level (pipx, etc.) with their plugins configured.
36
+ # Bundling llm would shadow the user's configured installation.
37
+ ]
38
+
39
+ [project.scripts]
40
+ llmess = "llmess.cli:main"
41
+
42
+ [project.urls]
43
+ Homepage = "https://github.com/tgies/llmess"
44
+ Repository = "https://github.com/tgies/llmess"
45
+
46
+ [tool.ruff]
47
+ target-version = "py38"
48
+ line-length = 100
49
+
50
+ [tool.ruff.lint]
51
+ select = [
52
+ "E", # pycodestyle errors
53
+ "F", # pyflakes
54
+ "I", # isort
55
+ "UP", # pyupgrade
56
+ ]
@@ -0,0 +1,3 @@
1
+ """llmess - A less pager that uses LLMs to hallucinate infinite file continuations."""
2
+
3
+ __version__ = "0.1.0"
@@ -0,0 +1,6 @@
1
+ """Entry point for python -m llmess."""
2
+
3
+ from .cli import main
4
+
5
+ if __name__ == "__main__":
6
+ main()