lightfoot 1.0.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 (106) hide show
  1. lightfoot-1.0.0/LICENSE +21 -0
  2. lightfoot-1.0.0/PKG-INFO +196 -0
  3. lightfoot-1.0.0/README.md +161 -0
  4. lightfoot-1.0.0/lightfoot/__init__.py +3 -0
  5. lightfoot-1.0.0/lightfoot/__main__.py +7 -0
  6. lightfoot-1.0.0/lightfoot/adapters/__init__.py +49 -0
  7. lightfoot-1.0.0/lightfoot/adapters/anthropic.py +259 -0
  8. lightfoot-1.0.0/lightfoot/adapters/base.py +224 -0
  9. lightfoot-1.0.0/lightfoot/adapters/chat.py +190 -0
  10. lightfoot-1.0.0/lightfoot/adapters/gemini.py +195 -0
  11. lightfoot-1.0.0/lightfoot/adapters/responses.py +201 -0
  12. lightfoot-1.0.0/lightfoot/agentplugins.py +151 -0
  13. lightfoot-1.0.0/lightfoot/agentskills.py +75 -0
  14. lightfoot-1.0.0/lightfoot/audit.py +146 -0
  15. lightfoot-1.0.0/lightfoot/cachesim.py +192 -0
  16. lightfoot-1.0.0/lightfoot/capture.py +109 -0
  17. lightfoot-1.0.0/lightfoot/cli.py +674 -0
  18. lightfoot-1.0.0/lightfoot/codexlog.py +197 -0
  19. lightfoot-1.0.0/lightfoot/config.py +386 -0
  20. lightfoot-1.0.0/lightfoot/dashboard.py +312 -0
  21. lightfoot-1.0.0/lightfoot/data/models.toml +165 -0
  22. lightfoot-1.0.0/lightfoot/data/skills/lightfoot-condensed-context/SKILL.md +21 -0
  23. lightfoot-1.0.0/lightfoot/data/skills/lightfoot-stats/SKILL.md +10 -0
  24. lightfoot-1.0.0/lightfoot/data/skills/lightfoot-why/SKILL.md +10 -0
  25. lightfoot-1.0.0/lightfoot/estimate.py +665 -0
  26. lightfoot-1.0.0/lightfoot/evaluate.py +462 -0
  27. lightfoot-1.0.0/lightfoot/fastjson.py +38 -0
  28. lightfoot-1.0.0/lightfoot/geminilog.py +286 -0
  29. lightfoot-1.0.0/lightfoot/guards.py +101 -0
  30. lightfoot-1.0.0/lightfoot/handoff.py +377 -0
  31. lightfoot-1.0.0/lightfoot/hookmode.py +243 -0
  32. lightfoot-1.0.0/lightfoot/idlehandoff.py +206 -0
  33. lightfoot-1.0.0/lightfoot/images.py +117 -0
  34. lightfoot-1.0.0/lightfoot/ingest.py +235 -0
  35. lightfoot-1.0.0/lightfoot/integrate.py +145 -0
  36. lightfoot-1.0.0/lightfoot/integrations.py +54 -0
  37. lightfoot-1.0.0/lightfoot/launch.py +589 -0
  38. lightfoot-1.0.0/lightfoot/maintenance.py +144 -0
  39. lightfoot-1.0.0/lightfoot/opencodehook.py +136 -0
  40. lightfoot-1.0.0/lightfoot/opencodelog.py +242 -0
  41. lightfoot-1.0.0/lightfoot/pricing.py +278 -0
  42. lightfoot-1.0.0/lightfoot/profiles.py +352 -0
  43. lightfoot-1.0.0/lightfoot/providers.py +136 -0
  44. lightfoot-1.0.0/lightfoot/prune.py +626 -0
  45. lightfoot-1.0.0/lightfoot/reports.py +612 -0
  46. lightfoot-1.0.0/lightfoot/server.py +834 -0
  47. lightfoot-1.0.0/lightfoot/statusline.py +298 -0
  48. lightfoot-1.0.0/lightfoot/store.py +587 -0
  49. lightfoot-1.0.0/lightfoot/subagents.py +103 -0
  50. lightfoot-1.0.0/lightfoot/support.py +92 -0
  51. lightfoot-1.0.0/lightfoot/text.py +276 -0
  52. lightfoot-1.0.0/lightfoot/transform.py +781 -0
  53. lightfoot-1.0.0/lightfoot/usage.py +219 -0
  54. lightfoot-1.0.0/lightfoot/validate.py +120 -0
  55. lightfoot-1.0.0/lightfoot/why.py +144 -0
  56. lightfoot-1.0.0/lightfoot.egg-info/PKG-INFO +196 -0
  57. lightfoot-1.0.0/lightfoot.egg-info/SOURCES.txt +104 -0
  58. lightfoot-1.0.0/lightfoot.egg-info/dependency_links.txt +1 -0
  59. lightfoot-1.0.0/lightfoot.egg-info/entry_points.txt +2 -0
  60. lightfoot-1.0.0/lightfoot.egg-info/requires.txt +12 -0
  61. lightfoot-1.0.0/lightfoot.egg-info/top_level.txt +1 -0
  62. lightfoot-1.0.0/pyproject.toml +86 -0
  63. lightfoot-1.0.0/setup.cfg +4 -0
  64. lightfoot-1.0.0/tests/test_agentplugins.py +63 -0
  65. lightfoot-1.0.0/tests/test_agentskills.py +60 -0
  66. lightfoot-1.0.0/tests/test_audit.py +36 -0
  67. lightfoot-1.0.0/tests/test_bench.py +117 -0
  68. lightfoot-1.0.0/tests/test_cachesim.py +54 -0
  69. lightfoot-1.0.0/tests/test_capture.py +71 -0
  70. lightfoot-1.0.0/tests/test_chat.py +156 -0
  71. lightfoot-1.0.0/tests/test_cli.py +202 -0
  72. lightfoot-1.0.0/tests/test_cline.py +222 -0
  73. lightfoot-1.0.0/tests/test_codexlog.py +73 -0
  74. lightfoot-1.0.0/tests/test_compaction.py +287 -0
  75. lightfoot-1.0.0/tests/test_config.py +83 -0
  76. lightfoot-1.0.0/tests/test_dashboard.py +71 -0
  77. lightfoot-1.0.0/tests/test_fastjson.py +36 -0
  78. lightfoot-1.0.0/tests/test_gemini.py +317 -0
  79. lightfoot-1.0.0/tests/test_geminilog.py +131 -0
  80. lightfoot-1.0.0/tests/test_guards.py +130 -0
  81. lightfoot-1.0.0/tests/test_handoff_eval.py +173 -0
  82. lightfoot-1.0.0/tests/test_hook_watch.py +71 -0
  83. lightfoot-1.0.0/tests/test_hookmode.py +142 -0
  84. lightfoot-1.0.0/tests/test_idlehandoff.py +126 -0
  85. lightfoot-1.0.0/tests/test_images.py +198 -0
  86. lightfoot-1.0.0/tests/test_integrate.py +87 -0
  87. lightfoot-1.0.0/tests/test_launch.py +149 -0
  88. lightfoot-1.0.0/tests/test_maintenance.py +208 -0
  89. lightfoot-1.0.0/tests/test_models_data.py +59 -0
  90. lightfoot-1.0.0/tests/test_opencode.py +90 -0
  91. lightfoot-1.0.0/tests/test_opencodehook.py +92 -0
  92. lightfoot-1.0.0/tests/test_opencodelog.py +160 -0
  93. lightfoot-1.0.0/tests/test_plugin.py +28 -0
  94. lightfoot-1.0.0/tests/test_properties.py +149 -0
  95. lightfoot-1.0.0/tests/test_providers.py +50 -0
  96. lightfoot-1.0.0/tests/test_prune.py +389 -0
  97. lightfoot-1.0.0/tests/test_release_manifests.py +89 -0
  98. lightfoot-1.0.0/tests/test_reports.py +22 -0
  99. lightfoot-1.0.0/tests/test_responses.py +327 -0
  100. lightfoot-1.0.0/tests/test_server.py +263 -0
  101. lightfoot-1.0.0/tests/test_statusline.py +169 -0
  102. lightfoot-1.0.0/tests/test_subagents.py +41 -0
  103. lightfoot-1.0.0/tests/test_support.py +23 -0
  104. lightfoot-1.0.0/tests/test_text.py +158 -0
  105. lightfoot-1.0.0/tests/test_transform.py +473 -0
  106. lightfoot-1.0.0/tests/test_why.py +83 -0
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Miska
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,196 @@
1
+ Metadata-Version: 2.4
2
+ Name: lightfoot
3
+ Version: 1.0.0
4
+ Summary: A local, cache-aware token-saving proxy for coding agents
5
+ Author: Miska
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://github.com/miska-voutilainen/lightfoot
8
+ Project-URL: Documentation, https://github.com/miska-voutilainen/lightfoot/blob/main/docs/guide.md
9
+ Project-URL: Changelog, https://github.com/miska-voutilainen/lightfoot/blob/main/CHANGELOG.md
10
+ Project-URL: Issues, https://github.com/miska-voutilainen/lightfoot/issues
11
+ Keywords: coding-agents,claude-code,codex,gemini-cli,opencode,aider,proxy,prompt-caching,tokens,llm
12
+ Classifier: Development Status :: 5 - Production/Stable
13
+ Classifier: Environment :: Console
14
+ Classifier: Intended Audience :: Developers
15
+ Classifier: Operating System :: OS Independent
16
+ Classifier: Programming Language :: Python :: 3
17
+ Classifier: Programming Language :: Python :: 3.11
18
+ Classifier: Programming Language :: Python :: 3.12
19
+ Classifier: Programming Language :: Python :: 3.13
20
+ Classifier: Programming Language :: Python :: 3.14
21
+ Classifier: Topic :: Software Development
22
+ Requires-Python: >=3.11
23
+ Description-Content-Type: text/markdown
24
+ License-File: LICENSE
25
+ Requires-Dist: starlette>=0.37
26
+ Requires-Dist: uvicorn>=0.29
27
+ Requires-Dist: httpx>=0.27
28
+ Requires-Dist: orjson>=3.10; platform_python_implementation == "CPython"
29
+ Provides-Extra: dev
30
+ Requires-Dist: pytest>=8; extra == "dev"
31
+ Requires-Dist: pytest-cov>=5; extra == "dev"
32
+ Requires-Dist: ruff>=0.6; extra == "dev"
33
+ Requires-Dist: hypothesis>=6.100; extra == "dev"
34
+ Dynamic: license-file
35
+
36
+ <h1 align="center">Lightfoot V1</h1>
37
+
38
+ <p align="center">
39
+ <a href="https://pypi.org/project/lightfoot/"><img src="https://img.shields.io/pypi/v/lightfoot.svg" alt="PyPI"/></a>
40
+ <a href="https://github.com/miska-voutilainen/lightfoot/actions/workflows/ci.yml"><img src="https://github.com/miska-voutilainen/lightfoot/actions/workflows/ci.yml/badge.svg" alt="CI"/></a>
41
+ <a href="https://www.python.org/downloads/"><img src="https://img.shields.io/badge/python-3.11%2B-blue.svg" alt="Python 3.11+"/></a>
42
+ <a href="LICENSE"><img src="https://img.shields.io/badge/license-MIT-green.svg" alt="License: MIT"/></a>
43
+ </p>
44
+
45
+ <p align="center">
46
+ <b>Long coding-agent sessions, cheaper. Without making them worse.</b>
47
+ </p>
48
+
49
+ Every turn of an agent session re-sends the whole conversation, and on long sessions most of the bill is the model re-reading it from the cache. Lightfoot is a local proxy between your agent and the model API that keeps that conversation lean. Start your agent through it (`lightfoot claude`, `lightfoot codex`, `lightfoot run -- <command>`) and nothing else changes.
50
+
51
+ - **Never mid-task.** Old turns are condensed only at your next prompt, past 200k tokens. Work in progress is never cut into.
52
+ - **Nothing is lost.** Everything condensed is saved under `.lightfoot/`, and the summary says where to find it.
53
+ - **Free to run.** No model calls. The summary is built from the conversation itself, and nothing leaves your machine except the request your agent was already sending.
54
+
55
+ ## Install
56
+
57
+ Paste this into your coding agent. It asks before installing anything optional, and shows each command before running it ([the instructions it follows](https://github.com/miska-voutilainen/lightfoot/blob/main/docs/agent-install.md)):
58
+
59
+ ```text
60
+ Install Lightfoot for me: run `curl -fsSL https://raw.githubusercontent.com/miska-voutilainen/lightfoot/main/docs/agent-install.md`, then follow those instructions step by step.
61
+ ```
62
+
63
+ **Or install it yourself.** Needs Python 3.11+ and uv (or pipx):
64
+
65
+ ```sh
66
+ uv tool install lightfoot # or: pipx install lightfoot
67
+ lightfoot estimate # what it would have saved on your past sessions (offline, free)
68
+ lightfoot claude # start your agent through Lightfoot; every argument passes through
69
+ ```
70
+
71
+ It starts in **shadow mode**: it measures what it would save and changes nothing. When `lightfoot stats` looks good, `lightfoot shadow off` turns the savings on. `lightfoot off` stops them immediately.
72
+
73
+ ---
74
+
75
+ ## See it in action
76
+
77
+ `lightfoot estimate` replays your existing session transcripts offline and prices them with and without Lightfoot. A real run on 139 sessions (8,646 API calls, API prices as of 2026-10-25):
78
+
79
+ | Where the cost went | Cost | Share |
80
+ | --- | ---: | ---: |
81
+ | Cache reads | $560.08 | 58.1% |
82
+ | Cache writes | $248.76 | 25.8% |
83
+ | Output | $155.75 | 16.1% |
84
+ | Uncached input | $0.14 | 0.0% |
85
+ | Total | $964.72 | 100% |
86
+
87
+ 58% of the money went to re-reading the conversation from the cache. That is the part Lightfoot shrinks: with it, the same sessions would have cost **$706.88**, a saving of **26.7%**. The longest sessions saved 35 to 46%; short sessions that never pass 200k tokens are left mostly alone and save close to nothing.
88
+
89
+ It is an estimate. Shadow mode measures the real thing on your own work, and `lightfoot eval` runs a paired comparison.
90
+
91
+ ---
92
+
93
+ ## What it does
94
+
95
+ Your agent sends its request to Lightfoot on your machine. Lightfoot condenses it, validates the result against the original, and forwards it to the model API. The response comes back unchanged.
96
+
97
+ | Rule | What it does |
98
+ | --- | --- |
99
+ | **Old-turn pruning** | Past 200k tokens, at your next prompt, the oldest turns become one summary. Your requests stay verbatim. |
100
+ | **Noise stripping** | ANSI codes, terminal redraws, progress bars and repeated lines go. |
101
+ | **Large-output trimming** | Output over ~4k tokens keeps its head, tail and every error line. The rest is saved to a file. |
102
+ | **JSON minification** | Pretty-printed JSON loses only its whitespace, checked by re-parsing. |
103
+ | **Stale reads and searches** | Superseded file reads and repeated searches become one-line stubs. |
104
+ | **Old images** | All but the 3 newest screenshots become a stub. Each image is saved to a file. |
105
+
106
+ Each rewrite happens once and is then replayed byte for byte on every later turn, so the prompt cache stays warm. Almost all of the saving comes from pruning old turns.
107
+
108
+ ---
109
+
110
+ ## What stays intact
111
+
112
+ - **Your words.** Your first message, your last 3 prompts with all their work, and at least the latest 100k tokens are kept as they were.
113
+ - **Fail-safe.** If a rewrite fails validation for any reason, your original request goes out instead.
114
+ - **Measured.** `lightfoot stats` counts how often the agent goes back for condensed content, and flags rules that cut too much.
115
+
116
+ ---
117
+
118
+ ## Supported agents
119
+
120
+ | Agent | Level | Status |
121
+ | --- | --- | --- |
122
+ | Claude Code | 3 · model summaries | Supported |
123
+ | Apps on the Claude Agent SDK | 2 · history edits | Supported |
124
+ | OpenAI Codex CLI | 0 · measure | Experimental |
125
+ | opencode | 0 · measure | Experimental |
126
+ | Gemini CLI | 0 · measure | Experimental, API-key auth only |
127
+ | Cline | wired | Experimental |
128
+ | Roo Code | wired | Experimental (project archived) |
129
+ | Aider | 0 · measure | Measured only |
130
+ | Other tools | wired | Experimental, via `lightfoot run -- <command>` |
131
+ | Cursor, Windsurf | - | Not possible: requests leave from their servers |
132
+
133
+ The level says how much is proven for each agent, from least to most: `wired` (built from its source, unit-tested) > `0 · measure` (its real traffic parsed) > `1 · output rules` > `2 · history edits` > `3 · model summaries` > `certified` (a passing paired eval). Experimental agents stay in shadow mode unless started with `--live --experimental`. [Details per agent](https://github.com/miska-voutilainen/lightfoot/blob/main/docs/guide.md#supported-agents).
134
+
135
+ ---
136
+
137
+ ## Common commands
138
+
139
+ ```sh
140
+ lightfoot claude # start an agent through Lightfoot (also: codex, opencode, gemini, aider)
141
+ lightfoot run -- <command> # any other tool that reads a base-URL variable
142
+ lightfoot estimate # what it would have saved on your past sessions
143
+ lightfoot stats # cost, savings and rule health per session
144
+ lightfoot why # what was condensed in a session, and where the full text is
145
+ lightfoot dashboard # a local report page
146
+ lightfoot shadow off # start saving (shadow on goes back to measuring)
147
+ lightfoot off # kill switch, immediate (lightfoot on resumes)
148
+ lightfoot doctor # check the setup
149
+ lightfoot plugins install --agent gemini # Lightfoot's extension for Gemini CLI (or --agent codex)
150
+ lightfoot skills install # the same guidance as skills, e.g. for opencode
151
+ ```
152
+
153
+ Resume sessions through Lightfoot too (`lightfoot claude --resume`); resuming without it re-sends the history uncondensed and rewrites the cache once. Hook mode (no proxy, for Claude Code and opencode), the Claude Code plugin and status line, every setting, and troubleshooting: **[the user guide](https://github.com/miska-voutilainen/lightfoot/blob/main/docs/guide.md)**.
154
+
155
+ ---
156
+
157
+ ## Privacy
158
+
159
+ - **Local only.** Listens on 127.0.0.1. Requests with other Host headers, and requests from browsers, are refused.
160
+ - **Your credentials** are forwarded unchanged and never written anywhere. With a subscription login, Lightfoot sends no requests of its own.
161
+ - **Project files can't take over.** A repository's `.lightfoot/config.toml` can't redirect your requests or run commands.
162
+ - **Retention.** Stored content is deleted 30 days after a session's last use. The cost ledger holds only token counts.
163
+ - **No telemetry**, no usage tracking, no analytics.
164
+
165
+ It uses about 50 MB of memory and almost no CPU when idle; a turn of a long session costs it a few tens of milliseconds. Works with API keys and with Pro and Max subscriptions ([what that means](https://github.com/miska-voutilainen/lightfoot/blob/main/docs/guide.md#pro-and-max-subscriptions)).
166
+
167
+ ---
168
+
169
+ ## Works well with Graphify and Obsidian
170
+
171
+ Both are optional, detected when present, and never installed unless you ask.
172
+
173
+ - **[Graphify](https://github.com/Graphify-Labs/graphify)** cuts the tokens spent *finding* code. Lightfoot points trimmed searches at `graphify-out/GRAPH_REPORT.md` and drops repeated graph queries.
174
+ - **[Obsidian](https://obsidian.md)** cuts the tokens spent *re-establishing* context. Lightfoot writes a handoff note (what's done, decisions, open threads) into your vault when a session ends.
175
+
176
+ ---
177
+
178
+ ## Learn more
179
+
180
+ - [User guide](https://github.com/miska-voutilainen/lightfoot/blob/main/docs/guide.md): every command and setting, agents, subscriptions, troubleshooting, uninstall
181
+ - [Architecture](https://github.com/miska-voutilainen/lightfoot/blob/main/docs/architecture.md): exactly what Lightfoot does to a request, and why
182
+ - [Comparison](https://github.com/miska-voutilainen/lightfoot/blob/main/docs/comparison.md): how it differs from other token-saving tools
183
+ - [Development](https://github.com/miska-voutilainen/lightfoot/blob/main/docs/development.md): set up, test, measure, release
184
+ - [Security](https://github.com/miska-voutilainen/lightfoot/blob/main/SECURITY.md): guarantees, and how to report a problem
185
+
186
+ ---
187
+
188
+ ## Contributing
189
+
190
+ Contributions are welcome. See **[CONTRIBUTING.md](https://github.com/miska-voutilainen/lightfoot/blob/main/CONTRIBUTING.md)** for the setup and the git workflow.
191
+
192
+ ---
193
+
194
+ ## License
195
+
196
+ [MIT](https://github.com/miska-voutilainen/lightfoot/blob/main/LICENSE). Lightfoot is an independent project, not affiliated with or endorsed by Anthropic, OpenAI, Google, Graphify or Obsidian.
@@ -0,0 +1,161 @@
1
+ <h1 align="center">Lightfoot V1</h1>
2
+
3
+ <p align="center">
4
+ <a href="https://pypi.org/project/lightfoot/"><img src="https://img.shields.io/pypi/v/lightfoot.svg" alt="PyPI"/></a>
5
+ <a href="https://github.com/miska-voutilainen/lightfoot/actions/workflows/ci.yml"><img src="https://github.com/miska-voutilainen/lightfoot/actions/workflows/ci.yml/badge.svg" alt="CI"/></a>
6
+ <a href="https://www.python.org/downloads/"><img src="https://img.shields.io/badge/python-3.11%2B-blue.svg" alt="Python 3.11+"/></a>
7
+ <a href="LICENSE"><img src="https://img.shields.io/badge/license-MIT-green.svg" alt="License: MIT"/></a>
8
+ </p>
9
+
10
+ <p align="center">
11
+ <b>Long coding-agent sessions, cheaper. Without making them worse.</b>
12
+ </p>
13
+
14
+ Every turn of an agent session re-sends the whole conversation, and on long sessions most of the bill is the model re-reading it from the cache. Lightfoot is a local proxy between your agent and the model API that keeps that conversation lean. Start your agent through it (`lightfoot claude`, `lightfoot codex`, `lightfoot run -- <command>`) and nothing else changes.
15
+
16
+ - **Never mid-task.** Old turns are condensed only at your next prompt, past 200k tokens. Work in progress is never cut into.
17
+ - **Nothing is lost.** Everything condensed is saved under `.lightfoot/`, and the summary says where to find it.
18
+ - **Free to run.** No model calls. The summary is built from the conversation itself, and nothing leaves your machine except the request your agent was already sending.
19
+
20
+ ## Install
21
+
22
+ Paste this into your coding agent. It asks before installing anything optional, and shows each command before running it ([the instructions it follows](https://github.com/miska-voutilainen/lightfoot/blob/main/docs/agent-install.md)):
23
+
24
+ ```text
25
+ Install Lightfoot for me: run `curl -fsSL https://raw.githubusercontent.com/miska-voutilainen/lightfoot/main/docs/agent-install.md`, then follow those instructions step by step.
26
+ ```
27
+
28
+ **Or install it yourself.** Needs Python 3.11+ and uv (or pipx):
29
+
30
+ ```sh
31
+ uv tool install lightfoot # or: pipx install lightfoot
32
+ lightfoot estimate # what it would have saved on your past sessions (offline, free)
33
+ lightfoot claude # start your agent through Lightfoot; every argument passes through
34
+ ```
35
+
36
+ It starts in **shadow mode**: it measures what it would save and changes nothing. When `lightfoot stats` looks good, `lightfoot shadow off` turns the savings on. `lightfoot off` stops them immediately.
37
+
38
+ ---
39
+
40
+ ## See it in action
41
+
42
+ `lightfoot estimate` replays your existing session transcripts offline and prices them with and without Lightfoot. A real run on 139 sessions (8,646 API calls, API prices as of 2026-10-25):
43
+
44
+ | Where the cost went | Cost | Share |
45
+ | --- | ---: | ---: |
46
+ | Cache reads | $560.08 | 58.1% |
47
+ | Cache writes | $248.76 | 25.8% |
48
+ | Output | $155.75 | 16.1% |
49
+ | Uncached input | $0.14 | 0.0% |
50
+ | Total | $964.72 | 100% |
51
+
52
+ 58% of the money went to re-reading the conversation from the cache. That is the part Lightfoot shrinks: with it, the same sessions would have cost **$706.88**, a saving of **26.7%**. The longest sessions saved 35 to 46%; short sessions that never pass 200k tokens are left mostly alone and save close to nothing.
53
+
54
+ It is an estimate. Shadow mode measures the real thing on your own work, and `lightfoot eval` runs a paired comparison.
55
+
56
+ ---
57
+
58
+ ## What it does
59
+
60
+ Your agent sends its request to Lightfoot on your machine. Lightfoot condenses it, validates the result against the original, and forwards it to the model API. The response comes back unchanged.
61
+
62
+ | Rule | What it does |
63
+ | --- | --- |
64
+ | **Old-turn pruning** | Past 200k tokens, at your next prompt, the oldest turns become one summary. Your requests stay verbatim. |
65
+ | **Noise stripping** | ANSI codes, terminal redraws, progress bars and repeated lines go. |
66
+ | **Large-output trimming** | Output over ~4k tokens keeps its head, tail and every error line. The rest is saved to a file. |
67
+ | **JSON minification** | Pretty-printed JSON loses only its whitespace, checked by re-parsing. |
68
+ | **Stale reads and searches** | Superseded file reads and repeated searches become one-line stubs. |
69
+ | **Old images** | All but the 3 newest screenshots become a stub. Each image is saved to a file. |
70
+
71
+ Each rewrite happens once and is then replayed byte for byte on every later turn, so the prompt cache stays warm. Almost all of the saving comes from pruning old turns.
72
+
73
+ ---
74
+
75
+ ## What stays intact
76
+
77
+ - **Your words.** Your first message, your last 3 prompts with all their work, and at least the latest 100k tokens are kept as they were.
78
+ - **Fail-safe.** If a rewrite fails validation for any reason, your original request goes out instead.
79
+ - **Measured.** `lightfoot stats` counts how often the agent goes back for condensed content, and flags rules that cut too much.
80
+
81
+ ---
82
+
83
+ ## Supported agents
84
+
85
+ | Agent | Level | Status |
86
+ | --- | --- | --- |
87
+ | Claude Code | 3 · model summaries | Supported |
88
+ | Apps on the Claude Agent SDK | 2 · history edits | Supported |
89
+ | OpenAI Codex CLI | 0 · measure | Experimental |
90
+ | opencode | 0 · measure | Experimental |
91
+ | Gemini CLI | 0 · measure | Experimental, API-key auth only |
92
+ | Cline | wired | Experimental |
93
+ | Roo Code | wired | Experimental (project archived) |
94
+ | Aider | 0 · measure | Measured only |
95
+ | Other tools | wired | Experimental, via `lightfoot run -- <command>` |
96
+ | Cursor, Windsurf | - | Not possible: requests leave from their servers |
97
+
98
+ The level says how much is proven for each agent, from least to most: `wired` (built from its source, unit-tested) > `0 · measure` (its real traffic parsed) > `1 · output rules` > `2 · history edits` > `3 · model summaries` > `certified` (a passing paired eval). Experimental agents stay in shadow mode unless started with `--live --experimental`. [Details per agent](https://github.com/miska-voutilainen/lightfoot/blob/main/docs/guide.md#supported-agents).
99
+
100
+ ---
101
+
102
+ ## Common commands
103
+
104
+ ```sh
105
+ lightfoot claude # start an agent through Lightfoot (also: codex, opencode, gemini, aider)
106
+ lightfoot run -- <command> # any other tool that reads a base-URL variable
107
+ lightfoot estimate # what it would have saved on your past sessions
108
+ lightfoot stats # cost, savings and rule health per session
109
+ lightfoot why # what was condensed in a session, and where the full text is
110
+ lightfoot dashboard # a local report page
111
+ lightfoot shadow off # start saving (shadow on goes back to measuring)
112
+ lightfoot off # kill switch, immediate (lightfoot on resumes)
113
+ lightfoot doctor # check the setup
114
+ lightfoot plugins install --agent gemini # Lightfoot's extension for Gemini CLI (or --agent codex)
115
+ lightfoot skills install # the same guidance as skills, e.g. for opencode
116
+ ```
117
+
118
+ Resume sessions through Lightfoot too (`lightfoot claude --resume`); resuming without it re-sends the history uncondensed and rewrites the cache once. Hook mode (no proxy, for Claude Code and opencode), the Claude Code plugin and status line, every setting, and troubleshooting: **[the user guide](https://github.com/miska-voutilainen/lightfoot/blob/main/docs/guide.md)**.
119
+
120
+ ---
121
+
122
+ ## Privacy
123
+
124
+ - **Local only.** Listens on 127.0.0.1. Requests with other Host headers, and requests from browsers, are refused.
125
+ - **Your credentials** are forwarded unchanged and never written anywhere. With a subscription login, Lightfoot sends no requests of its own.
126
+ - **Project files can't take over.** A repository's `.lightfoot/config.toml` can't redirect your requests or run commands.
127
+ - **Retention.** Stored content is deleted 30 days after a session's last use. The cost ledger holds only token counts.
128
+ - **No telemetry**, no usage tracking, no analytics.
129
+
130
+ It uses about 50 MB of memory and almost no CPU when idle; a turn of a long session costs it a few tens of milliseconds. Works with API keys and with Pro and Max subscriptions ([what that means](https://github.com/miska-voutilainen/lightfoot/blob/main/docs/guide.md#pro-and-max-subscriptions)).
131
+
132
+ ---
133
+
134
+ ## Works well with Graphify and Obsidian
135
+
136
+ Both are optional, detected when present, and never installed unless you ask.
137
+
138
+ - **[Graphify](https://github.com/Graphify-Labs/graphify)** cuts the tokens spent *finding* code. Lightfoot points trimmed searches at `graphify-out/GRAPH_REPORT.md` and drops repeated graph queries.
139
+ - **[Obsidian](https://obsidian.md)** cuts the tokens spent *re-establishing* context. Lightfoot writes a handoff note (what's done, decisions, open threads) into your vault when a session ends.
140
+
141
+ ---
142
+
143
+ ## Learn more
144
+
145
+ - [User guide](https://github.com/miska-voutilainen/lightfoot/blob/main/docs/guide.md): every command and setting, agents, subscriptions, troubleshooting, uninstall
146
+ - [Architecture](https://github.com/miska-voutilainen/lightfoot/blob/main/docs/architecture.md): exactly what Lightfoot does to a request, and why
147
+ - [Comparison](https://github.com/miska-voutilainen/lightfoot/blob/main/docs/comparison.md): how it differs from other token-saving tools
148
+ - [Development](https://github.com/miska-voutilainen/lightfoot/blob/main/docs/development.md): set up, test, measure, release
149
+ - [Security](https://github.com/miska-voutilainen/lightfoot/blob/main/SECURITY.md): guarantees, and how to report a problem
150
+
151
+ ---
152
+
153
+ ## Contributing
154
+
155
+ Contributions are welcome. See **[CONTRIBUTING.md](https://github.com/miska-voutilainen/lightfoot/blob/main/CONTRIBUTING.md)** for the setup and the git workflow.
156
+
157
+ ---
158
+
159
+ ## License
160
+
161
+ [MIT](https://github.com/miska-voutilainen/lightfoot/blob/main/LICENSE). Lightfoot is an independent project, not affiliated with or endorsed by Anthropic, OpenAI, Google, Graphify or Obsidian.
@@ -0,0 +1,3 @@
1
+ """A local, cache-aware token-saving proxy for coding agents."""
2
+
3
+ __version__ = "1.0.0"
@@ -0,0 +1,7 @@
1
+ """`python -m lightfoot`: the same as the `lightfoot` command."""
2
+
3
+ import sys
4
+
5
+ from .cli import main
6
+
7
+ sys.exit(main())
@@ -0,0 +1,49 @@
1
+ """Protocol adapters, chosen by request path."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import re
6
+
7
+ from .anthropic import AnthropicAdapter
8
+ from .base import Adapter, Index, Result, ToolCall, apply_changes, count_cache_markers
9
+ from .chat import ChatAdapter
10
+ from .gemini import GeminiAdapter
11
+ from .responses import ResponsesAdapter
12
+
13
+ ANTHROPIC = AnthropicAdapter()
14
+ RESPONSES = ResponsesAdapter()
15
+ GEMINI = GeminiAdapter()
16
+ CHAT = ChatAdapter()
17
+
18
+ GEMINI_PATH_RE = re.compile(r"(?:^|/)models/[^/]+:(?:stream)?generateContent$", re.I)
19
+
20
+
21
+ def for_path(method: str, path: str) -> Adapter | None:
22
+ """The adapter that rewrites this request, or None for pure passthrough."""
23
+ if method != "POST":
24
+ return None
25
+ path = path.rstrip("/")
26
+ if path.endswith("v1/messages"):
27
+ return ANTHROPIC
28
+ if path.endswith("/responses") or path == "responses":
29
+ return RESPONSES
30
+ if GEMINI_PATH_RE.search(path):
31
+ return GEMINI
32
+ if path.endswith("chat/completions"):
33
+ return CHAT
34
+ return None
35
+
36
+
37
+ __all__ = [
38
+ "ANTHROPIC",
39
+ "CHAT",
40
+ "GEMINI",
41
+ "RESPONSES",
42
+ "Adapter",
43
+ "Index",
44
+ "Result",
45
+ "ToolCall",
46
+ "apply_changes",
47
+ "count_cache_markers",
48
+ "for_path",
49
+ ]