@zenithfoundry/slm-gate 1.2.1

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. package/.env.example +669 -0
  2. package/LICENSE +21 -0
  3. package/README.md +317 -0
  4. package/configs/antigravity/.env.16gb.example +674 -0
  5. package/configs/antigravity/.env.24gb.example +674 -0
  6. package/configs/antigravity/.env.32gb.example +674 -0
  7. package/configs/antigravity/README.md +109 -0
  8. package/configs/claude-code/.env.16gb.example +674 -0
  9. package/configs/claude-code/.env.24gb.example +674 -0
  10. package/configs/claude-code/.env.32gb.example +674 -0
  11. package/configs/claude-code/README.md +52 -0
  12. package/configs/claude-desktop/.env.16gb.example +674 -0
  13. package/configs/claude-desktop/.env.24gb.example +674 -0
  14. package/configs/claude-desktop/.env.32gb.example +674 -0
  15. package/configs/claude-desktop/README.md +37 -0
  16. package/configs/cline-continue-opencode/.env.16gb.example +674 -0
  17. package/configs/cline-continue-opencode/.env.24gb.example +674 -0
  18. package/configs/cline-continue-opencode/.env.32gb.example +674 -0
  19. package/configs/cline-continue-opencode/README.md +34 -0
  20. package/configs/cursor/.env.16gb.example +674 -0
  21. package/configs/cursor/.env.24gb.example +674 -0
  22. package/configs/cursor/.env.32gb.example +674 -0
  23. package/configs/cursor/README.md +26 -0
  24. package/configs/generic-http/.env.16gb.example +674 -0
  25. package/configs/generic-http/.env.24gb.example +674 -0
  26. package/configs/generic-http/.env.32gb.example +674 -0
  27. package/configs/generic-http/README.md +20 -0
  28. package/configs/generic-stdio/.env.16gb.example +674 -0
  29. package/configs/generic-stdio/.env.24gb.example +674 -0
  30. package/configs/generic-stdio/.env.32gb.example +674 -0
  31. package/configs/generic-stdio/README.md +24 -0
  32. package/configs/preserve/README.md +26 -0
  33. package/configs/preserve/tls.json +61 -0
  34. package/dist/adapters/tech-lead-stack.js +38 -0
  35. package/dist/cache/index.js +173 -0
  36. package/dist/cli.js +256 -0
  37. package/dist/config.js +255 -0
  38. package/dist/dashboard/data.js +149 -0
  39. package/dist/dashboard/export.js +42 -0
  40. package/dist/dashboard/serve.js +63 -0
  41. package/dist/doctor.js +338 -0
  42. package/dist/hardware.js +126 -0
  43. package/dist/home-dir.js +39 -0
  44. package/dist/ledger/flush-lifecycle.js +50 -0
  45. package/dist/ledger/index.js +946 -0
  46. package/dist/ledger/report.js +69 -0
  47. package/dist/ledger/setup-dashboard.js +456 -0
  48. package/dist/ledger/smoke.js +37 -0
  49. package/dist/ledger/sync-config.js +177 -0
  50. package/dist/ledger/sync.js +307 -0
  51. package/dist/ledger/verify.js +185 -0
  52. package/dist/ledger/wipe-langfuse.js +130 -0
  53. package/dist/llm-gate/distill.js +239 -0
  54. package/dist/llm-gate/formats/anthropic.js +185 -0
  55. package/dist/llm-gate/formats/chat-completions.js +103 -0
  56. package/dist/llm-gate/formats/contract.js +29 -0
  57. package/dist/llm-gate/formats/gemini.js +84 -0
  58. package/dist/llm-gate/formats/internal.js +1 -0
  59. package/dist/llm-gate/formats/openai.js +77 -0
  60. package/dist/llm-gate/formats/responses.js +146 -0
  61. package/dist/llm-gate/forward.js +150 -0
  62. package/dist/llm-gate/index.js +40 -0
  63. package/dist/llm-gate/local-first.js +217 -0
  64. package/dist/llm-gate/pipeline.js +267 -0
  65. package/dist/llm-gate/server.js +289 -0
  66. package/dist/mcp-gate/ground.js +64 -0
  67. package/dist/mcp-gate/index.js +57 -0
  68. package/dist/mcp-gate/pipeline.js +252 -0
  69. package/dist/mcp-gate/server.js +302 -0
  70. package/dist/mcp-gate/tool-names.js +57 -0
  71. package/dist/models/check.js +26 -0
  72. package/dist/models/footprint.js +137 -0
  73. package/dist/models/helpers.js +91 -0
  74. package/dist/models/index.js +5 -0
  75. package/dist/models/reasoning.js +91 -0
  76. package/dist/models/roles.js +9 -0
  77. package/dist/models/slm.js +243 -0
  78. package/dist/models/types.js +1 -0
  79. package/dist/pricing/index.js +115 -0
  80. package/dist/pricing/plans.js +54 -0
  81. package/dist/pricing/providers.js +172 -0
  82. package/dist/resolver/index.js +277 -0
  83. package/dist/resolver/types.js +1 -0
  84. package/dist/setup/claim.js +41 -0
  85. package/dist/setup/gate-command.js +41 -0
  86. package/dist/setup/init.js +92 -0
  87. package/dist/setup/local-models.js +123 -0
  88. package/dist/setup/model-gate.js +220 -0
  89. package/dist/setup/notify.js +45 -0
  90. package/dist/setup/ollama-install.js +53 -0
  91. package/dist/setup/parent-watch.js +84 -0
  92. package/dist/setup/required-models.js +20 -0
  93. package/dist/setup/startup.js +132 -0
  94. package/dist/setup/tool-settings.js +101 -0
  95. package/dist/utils/backoff.js +47 -0
  96. package/dist/utils/compression.js +145 -0
  97. package/dist/utils/constants.js +22 -0
  98. package/dist/utils/duration.js +43 -0
  99. package/dist/utils/elision.js +556 -0
  100. package/dist/utils/embedding.js +32 -0
  101. package/dist/utils/entry-point.js +23 -0
  102. package/dist/utils/local-only.js +82 -0
  103. package/dist/utils/preserve-patterns.js +115 -0
  104. package/dist/utils/safety.js +30 -0
  105. package/dist/verifier/index.js +67 -0
  106. package/package.json +121 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 bronz3beard
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.
package/README.md ADDED
@@ -0,0 +1,317 @@
1
+ # slm-gate
2
+
3
+ **Make your AI coding plan last longer.** A small model on your own computer shrinks the large tool output your coding assistant sends to the paid cloud, and answers easy first messages itself. Works with Claude Code, Codex, Cursor, Gemini CLI, Cline and any MCP client. Runs on [Ollama](https://ollama.com/). Free and MIT-licensed.
4
+
5
+ **[See the live savings dashboard →](https://zenithfoundry.github.io/slm-gate/)** Measured from real daily use; benchmark runs are kept separate.
6
+
7
+ [![CI](https://github.com/zenithfoundry/slm-gate/actions/workflows/ci.yml/badge.svg)](https://github.com/zenithfoundry/slm-gate/actions/workflows/ci.yml)
8
+ [![CodeQL](https://github.com/zenithfoundry/slm-gate/actions/workflows/codeql.yml/badge.svg)](https://github.com/zenithfoundry/slm-gate/actions/workflows/codeql.yml)
9
+ [![OpenSSF Scorecard](https://api.scorecard.dev/projects/github.com/zenithfoundry/slm-gate/badge)](https://scorecard.dev/viewer/?uri=github.com/zenithfoundry/slm-gate)
10
+ [![License](https://img.shields.io/github/license/zenithfoundry/slm-gate)](LICENSE)
11
+ [![Version](https://img.shields.io/github/package-json/v/zenithfoundry/slm-gate)](package.json)
12
+ [![Last commit](https://img.shields.io/github/last-commit/zenithfoundry/slm-gate)](https://github.com/zenithfoundry/slm-gate/commits/main)
13
+ <br />
14
+ [![Node.js](https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fraw.githubusercontent.com%2Fzenithfoundry%2Fslm-gate%2Fmain%2Fpackage.json&query=%24.engines.node&label=node&color=brightgreen)](package.json)
15
+ [![TypeScript](https://img.shields.io/github/package-json/dependency-version/zenithfoundry/slm-gate/dev/typescript)](tsconfig.json)
16
+ [![MCP Compatible](https://img.shields.io/badge/MCP-Compatible-green.svg)](https://modelcontextprotocol.io/)
17
+ [![Runs on Ollama](https://img.shields.io/badge/runs%20on-Ollama-black)](https://ollama.com/)
18
+ [![Platform](https://img.shields.io/badge/platform-macOS%20%7C%20Linux-lightgrey)](docs/prerequisites-and-hardware.md)
19
+ [![Live dashboard](https://img.shields.io/badge/savings%20dashboard-live-blue)](https://zenithfoundry.github.io/slm-gate/)
20
+ [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)](https://github.com/zenithfoundry/slm-gate/pulls)
21
+
22
+ ---
23
+
24
+ ## Table of Contents
25
+
26
+ 1. [What is slm-gate?](#what-is-slm-gate)
27
+ 2. [How It Works: Visual](#how-it-works-visual)
28
+ 3. [Quick Start](#quick-start)
29
+ 4. [Documentation](#documentation)
30
+ 5. [Contributing & Security](#contributing--security)
31
+ 6. [Related Project](#related-project)
32
+ 7. [Intended Use](#intended-use)
33
+ 8. [License](#license)
34
+
35
+ ---
36
+
37
+ ## What is slm-gate?
38
+
39
+ `small-language-model-gate` (CLI shortname: **`slm-gate`**) is a **local AI pre-processing and routing layer** that sits in front of your AI coding assistant and quietly does two very useful things before anything reaches the paid cloud:
40
+
41
+ **It compresses the noise.** Your editor constantly packages up huge files, long logs, and sprawling system instructions and sends them to the cloud AI with every single message. Most of that is content the AI skims past. `slm-gate` intercepts this, runs a small, fast, free AI on your own computer, and strips it down to what actually matters — sending a fraction of the original text to the cloud.
42
+
43
+ **It answers easy questions locally.** Many conversations open with something a small model can answer — a quick fact, a short explanation, a greeting. `slm-gate` lets your local model try the first message of each conversation; if its answer passes a check, that request never reaches your paid plan at all. Anything else, and every slash command, goes to the cloud as normal.
44
+
45
+ The result: your paid AI plan lasts dramatically longer. Whether you're on a subscription (Claude Pro, Cursor Pro, Gemini Advanced, ChatGPT Plus) or paying per-token via an API key, you spend far less on the same amount of real work.
46
+
47
+ ### Why You Need This
48
+
49
+ Every AI subscription comes with rate limits. Claude Pro's five-hour windows, Cursor's monthly turn caps, ChatGPT Plus's hourly message limits — these aren't just numbers. Hit them mid-project and you're waiting hours to continue. `slm-gate` acts as a buffer. By intercepting routine traffic and compressing what does go to the cloud, your effective quota stretches much further.
50
+
51
+ On pay-per-token API plans (like `gpt-4o` or Claude Sonnet via API key), every token costs money. Sending a 500-line file when the model only needed 30 lines of context is a direct waste of budget. `slm-gate` eliminates that waste automatically.
52
+
53
+ ### Key Benefits
54
+
55
+ | Benefit | What It Means For You |
56
+ | :--- | :--- |
57
+ | **Quota Protection** | Fewer turns and tokens consumed means your subscription window lasts longer |
58
+ | **$0 Local Execution** | Small, repetitive queries answered free by your local machine |
59
+ | **Context Compression** | Large files, logs, and tool responses trimmed intelligently before hitting the cloud |
60
+ | **Privacy** | Less of your actual code and data leaves your machine |
61
+ | **Provider-Agnostic** | Works with Claude, GPT, Gemini, or any OpenAI-compatible endpoint |
62
+
63
+ ### What Gets Measured: Your Savings Dashboard
64
+
65
+ `slm-gate` records every decision it makes in a local database file on your computer (a SQLite database — think of it as a simple, fast spreadsheet that lives on your machine). For every request, it logs:
66
+
67
+ - How many tokens (units of text) were in the original payload
68
+ - How many tokens remained after compression
69
+ - Whether the request was answered locally (free) or forwarded to the cloud (answering locally is `llm-gate` only; see [How It Operates](docs/integration-layers.md))
70
+ - How long the local processing took
71
+ - The simulated dollar cost saved (for API key users)
72
+
73
+ **Checking your savings is one command:**
74
+
75
+ ```bash
76
+ pnpm run slm-gate metrics
77
+ ```
78
+
79
+ This prints a clean, offline summary showing tokens saved, compression ratio, requests handled locally, and how many extra minutes of subscription headroom you've gained — no API keys, no internet connection required.
80
+
81
+ **Want a visual dashboard?** Run `pnpm run dashboard` for the built-in one-page dashboard — per-cycle window time returned per provider, tokens saved, weekly charts and routing split, straight from the local ledger, publishable to GitHub Pages for free (see [The Metrics Dashboard](docs/daily-use.md#the-metrics-dashboard)). If you also set up [Langfuse](https://langfuse.com/) (a free, open-source observability tool), `slm-gate` will send traces there for session-by-session analysis. Both are optional — the local metrics command always works regardless.
82
+
83
+ ### How It Works: Visual
84
+
85
+ Five small diagrams, each answering one question. Read them in order. Numbers on the arrows show the order things happen.
86
+
87
+ #### 1. The big picture
88
+
89
+ slm-gate is two small servers on your computer, between your coding tool and the outside world. Both use small local models, run by Ollama:
90
+
91
+ - **Tool calls** go through the **MCP gate**. It passes each call to your toolbox, then trims long text in the result before your coding tool sees it: fixed rules first, then the small model summarises what is still too long. It also adds a short note on what your project uses, and lists any open decisions it found in the text, answered where it can.
92
+ - **Model requests** go through the **model gate**. On the first message of a conversation, the small model may answer by itself, and then the cloud is never called. Otherwise the gate shrinks new command, search and listing output, and sends the request to your AI provider with your own login.
93
+
94
+ If the small model fails or runs out of time, the text it was working on goes on as it was. Both gates record what they did in a local ledger (diagram 5).
95
+
96
+ ```mermaid
97
+ flowchart LR
98
+ tool(("Coding tool"))
99
+
100
+ subgraph mcpRow["Tool calls: MCP gate"]
101
+ direction LR
102
+ mcp["MCP gate"] -->|"pass on"| toolbox["Downstream MCP<br/>toolbox"]
103
+ toolbox -->|"raw result"| trim["MCP gate trims long text:<br/>rules first, then small model"]
104
+ end
105
+
106
+ subgraph llmRow["Model requests: model gate"]
107
+ direction LR
108
+ llm["Model gate"] -->|"first message"| answer["Small model<br/>tries to answer"]
109
+ llm -->|"later messages"| shrink["Shrink new command,<br/>search and listing output"]
110
+ answer -->|"no answer"| shrink
111
+ shrink --> cloud["Your AI provider<br/>(your login or API key)"]
112
+ end
113
+
114
+ tool --> mcp
115
+ trim -->|"smaller result"| tool
116
+ tool --> llm
117
+ answer -.->|"answer passed the check:<br/>reply, no cloud call"| tool
118
+ cloud -->|"reply, back through<br/>the gate unchanged"| tool
119
+ ```
120
+
121
+ #### 2. What happens to a tool call (MCP gate)
122
+
123
+ The MCP gate passes each tool call to your downstream toolbox unchanged. When the result comes back, it works on the text only: pictures, structured data and the error flag go back as the toolbox sent them. The gate also adds one tool of its own, `expand_elision`, which fetches back any lines it cut. With no toolbox set, the gate offers a single tool instead, `condition_prompt`, which runs the same steps on text you send it.
124
+
125
+ ```mermaid
126
+ flowchart LR
127
+ tool(("Coding tool"))
128
+ server["MCP server<br/>[mcp-gate/server.ts]"]
129
+ toolbox["Downstream MCP"]
130
+ cond["Condition the text<br/>[mcp-gate/pipeline.ts]"]
131
+ helpers["In order: saved result?,<br/>trim, project scan,<br/>open decisions"]
132
+ ledger[("Ledger")]
133
+ paid["Cloud model<br/>(CLOUD_API_KEY)"]
134
+
135
+ tool -->|"1. tool call"| server
136
+ server -->|"2. pass it on"| toolbox
137
+ toolbox -->|"3. raw result"| server
138
+ server -->|"4. text only"| cond
139
+ cond -->|"5. uses"| helpers
140
+ cond -->|"6. log it"| ledger
141
+ server -->|"7. smaller result"| tool
142
+ helpers -.->|"optional, off by default"| paid
143
+ tool -.->|"later: expand_elision"| server
144
+ ledger -.->|"the cut lines"| server
145
+ ```
146
+
147
+ | Step | File | What it does |
148
+ | :--- | :--- | :--- |
149
+ | Saved result | `src/ledger/index.ts`; `src/cache/index.ts` with `SEMCACHE=on` | If the same tool returned the same text before, sends the saved result and skips the steps below. With `SEMCACHE=on`, very similar text counts too. |
150
+ | Trim | `src/utils/elision.ts` | Leaves text under `DISTILL_MIN_TOKENS` alone. Otherwise saves the original for `expand_elision`, then cuts by tool name: a file keeps its outline and the lines about the task, a log keeps its errors and last 50 lines, a search keeps its first 50 lines. If it is still over `DISTILL_MAX_TOKENS`, the gate model summarises the plain prose, never code blocks, tables, headings or protected lines (and, by default, never skills or file reads). Anything still too long keeps only its start and end. |
151
+ | Project scan | `src/mcp-gate/ground.ts` | Reads the project's root files (`package.json`, `tsconfig.json`, lockfiles, `Cargo.toml`, `go.mod`) and adds a short list of what the project uses. Only when your coding tool shares the project folder. |
152
+ | Open decisions | `src/resolver/index.ts` | The brain model lists up to 3 open decisions in the text and answers each from your project's files or common practice; the gate model rates each one's risk. Low-risk answers found in your files are added as decided; the rest are added as questions to ask you, with a suggested answer. With `RESOLVER_CLOUD_TIER=on` and a budget set, unsure ones go to a paid cloud model using `CLOUD_API_KEY`. |
153
+
154
+ #### 3. What happens to a model request (model gate)
155
+
156
+ The model gate is a small server at `http://localhost:8787`. It reads four request formats (Anthropic Messages, OpenAI Chat Completions, OpenAI Responses and Gemini) and makes two tries to save you money before anything goes to your AI provider:
157
+
158
+ - **Step A, answer locally** (first message of a conversation only). Skipped for slash commands, for requests that demand a set output format or a tool call, and, when the coding tool offers the model tools, for messages that mention your code or files or ask about the assistant itself. Otherwise the gate model sorts the question by type, and only simple types are tried: short facts and formatting, plus yes/no, extraction, classification and spelling fixes when no tools are offered. The brain model answers 3 times by default, and the verifier (`src/verifier/index.ts`) rejects an empty answer, a hedging one ("I'm not sure") or answers that disagree. A passing answer goes back in the provider's own format and the cloud is never called. One try at a time, at most 6 seconds. `SEMCACHE=on` also reuses a saved answer to a very similar question, and `ROUTING_TUNE=on` stops trying types that usually fail.
159
+ - **Step B, shrink** (every request not answered locally). New command, search and listing output of at least `DISTILL_MIN_TOKENS` is trimmed the same way as in the MCP gate. File reads (including `cat` and similar run from a shell), web fetches and MCP tool results are never changed. Each decision is saved and resent unchanged on every later turn, so the provider's prompt cache keeps working. At most 3 seconds; after that, the original goes.
160
+
161
+ The request then goes to the provider its address belongs to, with every header your coding tool sent, so your own subscription login or API key is used; slm-gate never adds or swaps credentials. The reply streams back unchanged. Token counts, model lists and hello pings skip both steps.
162
+
163
+ ```mermaid
164
+ flowchart LR
165
+ tool(("Coding tool"))
166
+ server["Model gate<br/>[llm-gate/server.ts]"]
167
+ stepA["Step A: answer locally?<br/>[llm-gate/local-first.ts]"]
168
+ stepB["Step B: shrink new output<br/>[llm-gate/distill.ts]"]
169
+ fwd["Forward<br/>[llm-gate/forward.ts]"]
170
+ cloud["Your AI provider<br/>(your login or API key)"]
171
+ ledger[("Ledger")]
172
+
173
+ tool -->|"1. request"| server
174
+ server -->|"2. first message only"| stepA
175
+ stepA -.->|"passed the check: reply now"| tool
176
+ server -->|"3. not answered locally"| stepB
177
+ stepB -->|"4. smaller request"| fwd
178
+ fwd -->|"5. same headers"| cloud
179
+ cloud -->|"6. reply"| fwd
180
+ fwd -->|"7. reply, unchanged"| tool
181
+ server -->|"8. log it"| ledger
182
+ stepB -.->|"saved decisions"| ledger
183
+ ```
184
+
185
+ #### 4. How it starts, and what the CLI does
186
+
187
+ You rarely start anything by hand. Your coding tool starts the MCP gate. Before the MCP gate answers the tool (it waits at most 1.5 seconds), it starts the model gate in the background if nothing is running on its port, and checks that Ollama is running and every model your settings name is downloaded. It checks again 15 seconds later and then every minute, restarting the model gate if it stopped, unless you stopped it with `slm-gate stop`. With `LLM_GATE_AUTOSTART=off` it never starts the model gate and only checks once. It never starts Ollama or downloads a model. Problems show up as a desktop notification, and problems found at start-up are also passed to your AI assistant. The CLI is for doing this by hand, and for checks and reports.
188
+
189
+ ```mermaid
190
+ flowchart LR
191
+ tool(("Coding tool"))
192
+ you(("You"))
193
+ mcp["MCP gate<br/>[mcp-gate/index.ts]"]
194
+ checks["Start-up checks<br/>[setup/startup.ts]"]
195
+ ollama["Ollama"]
196
+ llm["Model gate<br/>[llm-gate/index.ts]"]
197
+ cli["CLI<br/>[cli.ts]"]
198
+
199
+ tool -->|"1. starts"| mcp
200
+ mcp -->|"2. at start, after 15 s,<br/>then every minute"| checks
201
+ checks -->|"3. running? models downloaded?"| ollama
202
+ checks -->|"4. start it if not running"| llm
203
+ checks -.->|"problems: desktop notification"| you
204
+ checks -.->|"problems at start:<br/>told to your AI assistant"| tool
205
+ you --> cli
206
+ cli -->|"start, stop, restart, serve"| llm
207
+ ```
208
+
209
+ | Command | Runs | Does |
210
+ | :--- | :--- | :--- |
211
+ | `start`, `stop`, `restart` | `src/setup/gate-command.ts` | Starts or stops the background model gate; `stop` lasts until `start`, `restart` or a reboot |
212
+ | `serve` | `src/llm-gate/index.ts` | Runs the model gate in this terminal (`--layer mcp` or `both` runs the MCP gate too) |
213
+ | `doctor` | `src/doctor.ts` | Preflight checks, and the exact line to paste into each coding tool |
214
+ | `config` | `src/config.ts` | Prints your settings |
215
+ | `models:check` | `src/models/check.ts` | Checks your models are downloaded and fit in memory |
216
+ | `metrics` | `harness/metrics.ts` | Rows, tokens and cost in the ledger, gate on vs off |
217
+ | `ledger:sync` | `src/ledger/sync.ts` | Sends ledger history to Langfuse |
218
+ | `setup-dashboard` | `src/ledger/setup-dashboard.ts` | Builds the Langfuse dashboard |
219
+ | `ledger:reset` | `src/cli.ts` | Deletes the local ledger and benchmark output |
220
+ | `bench` | `harness/run.ts` | Offline benchmark with an API key (not live traffic) |
221
+
222
+ #### 5. Where the data goes
223
+
224
+ Both gates write one row to the local ledger, a SQLite file (`output/ledger.sqlite` by default): one for each tool result the MCP gate conditions, and one for each model request the model gate answers or forwards. A row holds token counts, the route taken and timings, not the text itself. Rows for your coding tool's traffic carry no price; only the optional resolver cloud call and the benchmark record one. Cost saved (from the price list) and minutes saved (from each provider's usage-window size) are worked out for Langfuse as each row is written and again by `ledger:sync`; the dashboard works out minutes saved each time it loads. The same file also keeps saved results, the original of anything cut (for `expand_elision`), and the model gate's shrink decisions.
225
+
226
+ If all three Langfuse keys are set, each gate sends its new rows there as it runs (at start-up, every 15 seconds and at shutdown), and `ledger:sync` re-sends history.
227
+
228
+ ```mermaid
229
+ flowchart LR
230
+ gates["Both gates"]
231
+ ledger[("Ledger<br/>[ledger/index.ts]")]
232
+ pricing["Prices and window sizes<br/>[pricing/]"]
233
+ metrics["slm-gate metrics<br/>[harness/metrics.ts]"]
234
+ report["Tokens saved per day<br/>[ledger/report.ts]"]
235
+ dash["Dashboard<br/>[dashboard/serve.ts]"]
236
+ site["site/ folder for GitHub Pages<br/>[dashboard/export.ts]"]
237
+ langfuse["Langfuse (optional)"]
238
+
239
+ gates -->|"1. a row per request"| ledger
240
+ ledger --> metrics
241
+ ledger --> report
242
+ ledger --> dash
243
+ ledger --> site
244
+ pricing -->|"minutes saved"| dash
245
+ pricing -->|"cost and minutes saved"| langfuse
246
+ ledger -.->|"new rows every 15 s;<br/>ledger:sync for history"| langfuse
247
+ ```
248
+
249
+ | Reader | Command | Shows |
250
+ | :--- | :--- | :--- |
251
+ | Metrics | `slm-gate metrics` | Rows, tokens and cost, gate on vs off |
252
+ | Report | `pnpm run ledger:report` | Tokens saved per day and all-time |
253
+ | Dashboard | `pnpm run dashboard` | Minutes of each provider's usage window returned, tokens saved, weekly charts, routing split, local-answer accuracy |
254
+ | Static copy | `pnpm run dashboard:export` | The dashboard with numbers and dates only, written to `site/` for the Pages workflow |
255
+ | Langfuse | runs by itself; `slm-gate ledger:sync` for history | A trace per request, with cost, tokens and minutes saved |
256
+
257
+ ---
258
+
259
+ ## Quick Start
260
+
261
+ You need Node.js 22+, pnpm 10+ and [Ollama](https://ollama.com/download) running. This is the setup for a 16 GB machine with Claude Code; other editors and machine sizes are in the [setup guide](docs/setup.md).
262
+
263
+ ```bash
264
+ git clone https://github.com/zenithfoundry/slm-gate.git small-language-model-gate
265
+ cd small-language-model-gate
266
+ pnpm install && pnpm run build
267
+ cp configs/claude-code/.env.16gb.example .env
268
+ ollama pull qwen2.5-coder:3b && ollama pull qwen2.5-coder:0.5b
269
+ claude mcp add --scope user slm-gate -- node "$PWD/dist/mcp-gate/index.js"
270
+ node dist/cli.js doctor
271
+ ```
272
+
273
+ Then restart Claude Code. `doctor` checks Ollama, your models and the model gate, and prints the one line to add to Claude Code's settings if you also want its model requests to go through the gate ([Layer 2](docs/integration-layers.md#layer-2-llm-gate--the-model-endpoint-proxy)).
274
+
275
+ ---
276
+
277
+ ## Documentation
278
+
279
+ Setup and reference guides live in [`docs/`](docs/README.md). The first time through, read them in this order:
280
+
281
+ 1. [Prerequisites & Hardware Sizing](docs/prerequisites-and-hardware.md): what to install, and which local models fit your machine's memory
282
+ 2. [How It Operates](docs/integration-layers.md): the two layers, who pays for what, and which coding tools work with each
283
+ 3. [Step-by-Step Setup](docs/setup.md): clone, build, download models, and connect your editor
284
+ 4. [Configuration](docs/configuration.md): RAM presets, the 16 GB baseline `.env`, and every setting explained
285
+ 5. [Verification & Day-to-Day Use](docs/daily-use.md): the health check, fixing start-up problems, checking savings, the dashboard
286
+ 6. [Architecture & Advanced Features](docs/advanced.md): the hosted small-model fallback, and a rule for contributors
287
+
288
+ Also: [walkthroughs](docs/README.md#walkthroughs), [analytics & observability](docs/analytics-and-observability.md), [architecture overview](ARCHITECTURE.md), and [every doc on one page](docs/README.md).
289
+
290
+ ---
291
+
292
+ ## Contributing & Security
293
+
294
+ Pull requests are welcome; read the [contributing guide](.github/CONTRIBUTING.md) first. For help, and what is supported, see [support](SUPPORT.md). Please report security problems privately, as the [security policy](SECURITY.md) describes, not in a public issue.
295
+
296
+ ---
297
+
298
+ ## Related Project
299
+
300
+ > [!NOTE]
301
+ > **Tech-Lead-Stack:** An agent-agnostic library of Markdown "skills" plus an MCP
302
+ > server that turns Claude, Gemini, or GPT into a full software-delivery team (planning,
303
+ > building, review, security, release), organized around a nine-phase lifecycle. Its
304
+ > self-correcting Reflexion loop grades implementation plans against four engineering
305
+ > pillars before any code is written. `slm-gate` can sit in front of it and shrink its skill payloads.
306
+ >
307
+ > <a href="https://github.com/bronz3beard/ai.tech-lead-stack" target="_blank" rel="noopener noreferrer">Explore tech-lead-stack on GitHub →</a>
308
+
309
+ ---
310
+
311
+ ## Intended Use
312
+
313
+ This software runs locally and drives third-party AI tools and models that **you** install and authenticate. You are responsible for complying with the terms of any tool, model, or subscription you connect to it. It is designed for single-user, local use with your own accounts — it does not proxy or share third-party credentials between users. Provided "as is" under the MIT License, without warranty of any kind.
314
+
315
+ ## License
316
+
317
+ [MIT](LICENSE)