@noorslvt/shev 0.0.0-stage → 0.2.0

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.
package/Cargo.toml ADDED
@@ -0,0 +1,32 @@
1
+ [package]
2
+ name = "shev"
3
+ version = "0.2.0"
4
+ edition = "2024"
5
+ description = "A simple Jev-like decision making tool, without the hype."
6
+ license = "Apache-2.0"
7
+ repository = "https://github.com/aditauqir/shev"
8
+ readme = "README.md"
9
+ # explicit targets: the TUI is `shev`, the line CLI is `shev-cli`
10
+ autobins = false
11
+ default-run = "shev"
12
+
13
+ [[bin]]
14
+ name = "shev"
15
+ path = "src/bin/shev.rs"
16
+
17
+ [[bin]]
18
+ name = "shev-cli"
19
+ path = "src/main.rs"
20
+
21
+ [dependencies]
22
+ ratatui = { version = "0.30.2", default-features = false, features = ["crossterm"] }
23
+ reqwest = { version = "0.12", default-features = false, features = ["blocking", "json", "rustls-tls"] }
24
+ serde = { version = "1", features = ["derive"] }
25
+ serde_json = "1"
26
+ toml = "0.8"
27
+ unicode-width = "0.2"
28
+ unicode-segmentation = "1"
29
+ sha2 = "0.10"
30
+
31
+ [profile.release]
32
+ opt-level = 2
package/LICENSE ADDED
@@ -0,0 +1,201 @@
1
+ Apache License
2
+ Version 2.0, January 2004
3
+ http://www.apache.org/licenses/
4
+
5
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6
+
7
+ 1. Definitions.
8
+
9
+ "License" shall mean the terms and conditions for use, reproduction,
10
+ and distribution as defined by Sections 1 through 9 of this document.
11
+
12
+ "Licensor" shall mean the copyright owner or entity authorized by
13
+ the copyright owner that is granting the License.
14
+
15
+ "Legal Entity" shall mean the union of the acting entity and all
16
+ other entities that control, are controlled by, or are under common
17
+ control with that entity. For the purposes of this definition,
18
+ "control" means (i) the power, direct or indirect, to cause the
19
+ direction or management of such entity, whether by contract or
20
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
21
+ outstanding shares, or (iii) beneficial ownership of such entity.
22
+
23
+ "You" (or "Your") shall mean an individual or Legal Entity
24
+ exercising permissions granted by this License.
25
+
26
+ "Source" form shall mean the preferred form for making modifications,
27
+ including but not limited to software source code, documentation
28
+ source, and configuration files.
29
+
30
+ "Object" form shall mean any form resulting from mechanical
31
+ transformation or translation of a Source form, including but
32
+ not limited to compiled object code, generated documentation,
33
+ and conversions to other media types.
34
+
35
+ "Work" shall mean the work of authorship, whether in Source or
36
+ Object form, made available under the License, as indicated by a
37
+ copyright notice that is included in or attached to the work
38
+ (an example is provided in the Appendix below).
39
+
40
+ "Derivative Works" shall mean any work, whether in Source or Object
41
+ form, that is based on (or derived from) the Work and for which the
42
+ editorial revisions, annotations, elaborations, or other modifications
43
+ represent, as a whole, an original work of authorship. For the purposes
44
+ of this License, Derivative Works shall not include works that remain
45
+ separable from, or merely link (or bind by name) to the interfaces of,
46
+ the Work and Derivative Works thereof.
47
+
48
+ "Contribution" shall mean any work of authorship, including
49
+ the original version of the Work and any modifications or additions
50
+ to that Work or Derivative Works thereof, that is intentionally
51
+ submitted to Licensor for inclusion in the Work by the copyright owner
52
+ or by an individual or Legal Entity authorized to submit on behalf of
53
+ the copyright owner. For the purposes of this definition, "submitted"
54
+ means any form of electronic, verbal, or written communication sent
55
+ to the Licensor or its representatives, including but not limited to
56
+ communication on electronic mailing lists, source code control systems,
57
+ and issue tracking systems that are managed by, or on behalf of, the
58
+ Licensor for the purpose of discussing and improving the Work, but
59
+ excluding communication that is conspicuously marked or otherwise
60
+ designated in writing by the copyright owner as "Not a Contribution."
61
+
62
+ "Contributor" shall mean Licensor and any individual or Legal Entity
63
+ on behalf of whom a Contribution has been received by Licensor and
64
+ subsequently incorporated within the Work.
65
+
66
+ 2. Grant of Copyright License. Subject to the terms and conditions of
67
+ this License, each Contributor hereby grants to You a perpetual,
68
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69
+ copyright license to reproduce, prepare Derivative Works of,
70
+ publicly display, publicly perform, sublicense, and distribute the
71
+ Work and such Derivative Works in Source or Object form.
72
+
73
+ 3. Grant of Patent License. Subject to the terms and conditions of
74
+ this License, each Contributor hereby grants to You a perpetual,
75
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76
+ (except as stated in this section) patent license to make, have made,
77
+ use, offer to sell, sell, import, and otherwise transfer the Work,
78
+ where such license applies only to those patent claims licensable
79
+ by such Contributor that are necessarily infringed by their
80
+ Contribution(s) alone or by combination of their Contribution(s)
81
+ with the Work to which such Contribution(s) was submitted. If You
82
+ institute patent litigation against any entity (including a
83
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
84
+ or a Contribution incorporated within the Work constitutes direct
85
+ or contributory patent infringement, then any patent licenses
86
+ granted to You under this License for that Work shall terminate
87
+ as of the date such litigation is filed.
88
+
89
+ 4. Redistribution. You may reproduce and distribute copies of the
90
+ Work or Derivative Works thereof in any medium, with or without
91
+ modifications, and in Source or Object form, provided that You
92
+ meet the following conditions:
93
+
94
+ (a) You must give any other recipients of the Work or
95
+ Derivative Works a copy of this License; and
96
+
97
+ (b) You must cause any modified files to carry prominent notices
98
+ stating that You changed the files; and
99
+
100
+ (c) You must retain, in the Source form of any Derivative Works
101
+ that You distribute, all copyright, patent, trademark, and
102
+ attribution notices from the Source form of the Work,
103
+ excluding those notices that do not pertain to any part of
104
+ the Derivative Works; and
105
+
106
+ (d) If the Work includes a "NOTICE" text file as part of its
107
+ distribution, then any Derivative Works that You distribute must
108
+ include a readable copy of the attribution notices contained
109
+ within such NOTICE file, excluding those notices that do not
110
+ pertain to any part of the Derivative Works, in at least one
111
+ of the following places: within a NOTICE text file distributed
112
+ as part of the Derivative Works; within the Source form or
113
+ documentation, if provided along with the Derivative Works; or,
114
+ within a display generated by the Derivative Works, if and
115
+ wherever such third-party notices normally appear. The contents
116
+ of the NOTICE file are for informational purposes only and
117
+ do not modify the License. You may add Your own attribution
118
+ notices within Derivative Works that You distribute, alongside
119
+ or as an addendum to the NOTICE text from the Work, provided
120
+ that such additional attribution notices cannot be construed
121
+ as modifying the License.
122
+
123
+ You may add Your own copyright statement to Your modifications and
124
+ may provide additional or different license terms and conditions
125
+ for use, reproduction, or distribution of Your modifications, or
126
+ for any such Derivative Works as a whole, provided Your use,
127
+ reproduction, and distribution of the Work otherwise complies with
128
+ the conditions stated in this License.
129
+
130
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
131
+ any Contribution intentionally submitted for inclusion in the Work
132
+ by You to the Licensor shall be under the terms and conditions of
133
+ this License, without any additional terms or conditions.
134
+ Notwithstanding the above, nothing herein shall supersede or modify
135
+ the terms of any separate license agreement you may have executed
136
+ with Licensor regarding such Contributions.
137
+
138
+ 6. Trademarks. This License does not grant permission to use the trade
139
+ names, trademarks, service marks, or product names of the Licensor,
140
+ except as required for reasonable and customary use in describing the
141
+ origin of the Work and reproducing the content of the NOTICE file.
142
+
143
+ 7. Disclaimer of Warranty. Unless required by applicable law or
144
+ agreed to in writing, Licensor provides the Work (and each
145
+ Contributor provides its Contributions) on an "AS IS" BASIS,
146
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147
+ implied, including, without limitation, any warranties or conditions
148
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149
+ PARTICULAR PURPOSE. You are solely responsible for determining the
150
+ appropriateness of using or redistributing the Work and assume any
151
+ risks associated with Your exercise of permissions under this License.
152
+
153
+ 8. Limitation of Liability. In no event and under no legal theory,
154
+ whether in tort (including negligence), contract, or otherwise,
155
+ unless required by applicable law (such as deliberate and grossly
156
+ negligent acts) or agreed to in writing, shall any Contributor be
157
+ liable to You for damages, including any direct, indirect, special,
158
+ incidental, or consequential damages of any character arising as a
159
+ result of this License or out of the use or inability to use the
160
+ Work (including but not limited to damages for loss of goodwill,
161
+ work stoppage, computer failure or malfunction, or any and all
162
+ other commercial damages or losses), even if such Contributor
163
+ has been advised of the possibility of such damages.
164
+
165
+ 9. Accepting Warranty or Additional Liability. While redistributing
166
+ the Work or Derivative Works thereof, You may choose to offer,
167
+ and charge a fee for, acceptance of support, warranty, indemnity,
168
+ or other liability obligations and/or rights consistent with this
169
+ License. However, in accepting such obligations, You may act only
170
+ on Your own behalf and on Your sole responsibility, not on behalf
171
+ of any other Contributor, and only if You agree to indemnify,
172
+ defend, and hold each Contributor harmless for any liability
173
+ incurred by, or claims asserted against, such Contributor by reason
174
+ of your accepting any such warranty or additional liability.
175
+
176
+ END OF TERMS AND CONDITIONS
177
+
178
+ APPENDIX: How to apply the Apache License to your work.
179
+
180
+ To apply the Apache License to your work, attach the following
181
+ boilerplate notice, with the fields enclosed by brackets "[]"
182
+ replaced with your own identifying information. (Don't include
183
+ the brackets!) The text should be enclosed in the appropriate
184
+ comment syntax for the file format. We also recommend that a
185
+ file or class name and description of purpose be included on the
186
+ same "printed page" as the copyright notice for easier
187
+ identification within third-party archives.
188
+
189
+ Copyright [yyyy] [name of copyright owner]
190
+
191
+ Licensed under the Apache License, Version 2.0 (the "License");
192
+ you may not use this file except in compliance with the License.
193
+ You may obtain a copy of the License at
194
+
195
+ http://www.apache.org/licenses/LICENSE-2.0
196
+
197
+ Unless required by applicable law or agreed to in writing, software
198
+ distributed under the License is distributed on an "AS IS" BASIS,
199
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200
+ See the License for the specific language governing permissions and
201
+ limitations under the License.
package/README.md CHANGED
@@ -1,3 +1,411 @@
1
- # Temporary Holding Version
1
+ # shev
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ **A simple Jev-like decision maker. Without the hype.**
4
+
5
+ Hand it one whole message — an email, a ticket, a review, a doc, whatever you
6
+ pasted out of the support queue — and tell it what you want done with it. It
7
+ hands back **one** decision, as JSON:
8
+
9
+ ```json
10
+ {
11
+ "actionable": "Reply to Sam and cc finance about the overdue March invoice.",
12
+ "take_action": true,
13
+ "confidence": 95,
14
+ "generated_response": "Hi Sam, ... (the reply, written out)"
15
+ }
16
+ ```
17
+
18
+ That's the whole thing. No agents. No orchestration. No prompt engineering. No
19
+ five-hundred-token preamble to memorise. One message in, one decision out, in a
20
+ file you can just read.
21
+
22
+ - **Whole message, judged once.** It doesn't chop the thing into paragraphs and
23
+ it doesn't go line by line. One message, one decision.
24
+ - **You say what you want.** It asks before it answers, and what you want done
25
+ is what drives the reply it writes.
26
+ - **The answer has a shape.** `actionable` (a string), `take_action` (a
27
+ boolean), `confidence` (an integer, always in `[34, 100]`). No tuple you have
28
+ to guess at.
29
+ - **Runs on your Mac if you want.** DeepSeek over the network, or a small
30
+ ternary MLX model sitting right there on the machine. Switch whenever.
31
+ - **It writes it all down.** Decisions pile up in `responses.json` as
32
+ `response1`, `response2`, … and other models can read them over MCP.
33
+
34
+ ## Install
35
+
36
+ One line, copy-pasteable:
37
+
38
+ ```sh
39
+ curl -fsSL https://raw.githubusercontent.com/aditauqir/shev/main/install.sh | bash
40
+ ```
41
+
42
+ Then type **`shev`**. The installer uses a user bin directory already on PATH
43
+ where possible. Otherwise it adds a small, removable PATH block to your shell
44
+ profile; open a new terminal and type `shev`—no manual shell edits needed.
45
+
46
+ Prefer npm?
47
+
48
+ ```sh
49
+ npm install -g git+https://github.com/aditauqir/shev.git
50
+ shev
51
+ ```
52
+
53
+ This installs the package **`@noorslvt/shev`**, with the terminal commands
54
+ `shev` and `shev-cli`. The unscoped npm registry name `shev` belongs to an
55
+ unrelated project; **do not use `npm install -g shev`** for this tool. This
56
+ GitHub install does not require a separate npm registry publication.
57
+
58
+ Both installers prefer a matching prebuilt release and otherwise build with
59
+ Rust (installing the minimal Rust toolchain if necessary). npm uses the source
60
+ shipped in its package, not an unrelated registry binary. macOS/Linux are
61
+ supported by the npm launcher; Windows users can use WSL.
62
+
63
+ Got Rust already? Same thing, just as short:
64
+
65
+ ```sh
66
+ cargo install --git https://github.com/aditauqir/shev
67
+ ```
68
+
69
+ ### Uninstall
70
+
71
+ For full cleanup, whether installed with curl or npm, close other running shev
72
+ sessions first:
73
+
74
+ ```sh
75
+ shev --uninstall --dry-run # preview paths; delete nothing
76
+ shev --uninstall # confirm before removal
77
+ # or: shev --uninstall --yes
78
+ ```
79
+
80
+ This removes registered shev binaries, its saved keys/config, local model data,
81
+ tracked chat records, unchanged tracked shev MCP registrations, and the exact PATH
82
+ blocks added by its installer. A full npm-backed uninstall also runs npm's
83
+ package removal. Modified binaries/profile blocks, externally managed weights,
84
+ host recovery backups, unrelated host settings,
85
+ non-chat metadata in export files, source checkouts, and shared tools/caches
86
+ (Rust, Node, uv, Codex, OpenCode) are not deleted.
87
+
88
+ You can also remove the npm package directly:
89
+
90
+ ```sh
91
+ npm uninstall -g @noorslvt/shev
92
+ ```
93
+
94
+ This removes the npm package and its binaries. **Modern npm does not execute
95
+ uninstall hooks**, so it cannot also remove persistent settings/models/history
96
+ or external MCP registrations. Use **`shev --uninstall`** for full cleanup;
97
+ it handles the npm package removal too. Persistent npm data deliberately lives
98
+ outside the package so a normal npm upgrade does not erase private keys,
99
+ history, or model downloads. No background uninstall watchers or npm overrides
100
+ are installed.
101
+
102
+ ## What you need
103
+
104
+ - **Best for local use:** Apple Silicon — **M1 or newer, 16 GB of RAM and up**.
105
+ - **8 GB** will fit the local model too, but it's tight.
106
+ - **Everything else:** runs anywhere with a DeepSeek API key. No Mac required.
107
+
108
+ <sub>Only the local model cares about the Mac. It runs on MLX, and MLX is Apple
109
+ Silicon only, so "run it on your machine" means "run it on a Mac". Point shev at
110
+ a DeepSeek key instead and the work goes over the network — then it builds and
111
+ runs on any platform Rust does.</sub>
112
+
113
+ ## Quick start
114
+
115
+ ```sh
116
+ shev
117
+ ```
118
+
119
+ 1. Bonsai is the default. Install it through `/model` if needed; no API key is
120
+ required. DeepSeek is optional through `/model`; its key is stored at
121
+ `~/.config/shev/config.json` as `0600`.
122
+ 2. Type or paste the whole message. **enter** sends it, **ctrl+j** drops a new
123
+ line in the middle of a multi-line one.
124
+ 3. Say what you want done with it — "draft a short reply", "does this need me
125
+ today", "where's the risk here".
126
+ 4. Read the decision. **enter** starts the next one, or click
127
+ `▸ open responses.json in Finder` and go look at the file.
128
+
129
+ After the first run it's just: run `shev`, type, done.
130
+
131
+ ## The TUI
132
+
133
+ The home/start screen has a white ASCII wordmark directly over the wallpaper,
134
+ without a background box or JSON pane. Once a chat starts, two windows appear:
135
+
136
+ - **Left, the model output.** Every decision as a clean field list. The prompt box sits flush at the
137
+ foot, with its mode line ("Build · bonsai (local) · …") on the last row.
138
+ - **Right, this turn's JSON only.** The raw record for the decision you are on,
139
+ so you can read the file without leaving the screen. Drag across JSON text to
140
+ select it; releasing the mouse copies exactly the selection and shows
141
+ **✓ copied to clipboard** at the top center. The mouse wheel scrolls the JSON
142
+ independently. `/copy json` copies the complete record, including off-screen text.
143
+
144
+ Text panels use **`#0F0E08`** over the dimmed photo wallpaper. Type `/` for commands:
145
+ Panels are inset from the terminal edges. Skills/tools menus show names only;
146
+ long menus scroll around the selected row instead of clipping it off-screen.
147
+
148
+ | Command | What it does |
149
+ | --- | --- |
150
+ | `/file <path>` | Load a message from a file (drag-and-drop works too) |
151
+ | `/copy [json]` | Copy selected JSON or the last response; `json` copies the complete record |
152
+ | `/key` | Enter or replace the DeepSeek API key |
153
+ | `/cancel` | Abort the request in flight |
154
+ | `/clear` | Clear the visible chat and input; keep saved history |
155
+ | `/reset` | Confirm clearing the chat, all saved history, loaded context and counters; keep keys/models |
156
+ | `/help` | Show the keybindings |
157
+ | `/model` | Pick the model and manage it (keys, install, uninstall) |
158
+ | `/home` | Back to the home screen (the transcript is kept) |
159
+ | `/history` | Jump through the decisions so far |
160
+ | `/mcp` | Install, remove, or report the local MCP bridge |
161
+ | `/skills` | Load existing skill guidance; `/skills off` clears supporting context |
162
+ | `/tools [server]` | Connect to a registered MCP server and inspect read-only tools |
163
+ | `/tool server/tool <JSON>` | Call a read-only tool and attach its result to the next decision |
164
+ | `/plugins` | Show host-plugin compatibility limits |
165
+ | `/quit` | Leave |
166
+
167
+ Handy keys:
168
+
169
+ | Key | What it does |
170
+ | --- | --- |
171
+ | `enter` | Send the message, then the intent |
172
+ | `ctrl+j` | Newline inside the box |
173
+ | `ctrl+t` | Switch the model (DeepSeek ↔ Bonsai) |
174
+ | `ctrl+h` | Open the history (same as `/history`) |
175
+ | `ctrl+d` in history | Confirm deletion of only the selected saved entry |
176
+ | `ctrl+y` | Copy selected JSON, or the last generated response |
177
+ | `ctrl+c` | Quit |
178
+
179
+ `/clear` starts a fresh chat view; `/history` can reopen retained records.
180
+ `/reset` and history deletion default to **cancel** in their confirmation menus.
181
+ Confirmed changes update the responses file, so MCP clients see them too.
182
+
183
+ ## Models
184
+
185
+ `/model` switches between two backends and manages each one.
186
+
187
+ **DeepSeek** — the secondary, explicitly selected remote option; needs an API key. Options: enter a new
188
+ key, remove the stored key, or cancel.
189
+
190
+ **Bonsai (default)** — `prism-ml/Ternary-Bonsai-2-2B-mlx-2bit`, a small ternary model that
191
+ runs on Apple Silicon through MLX. Options: install it from the internet
192
+ (about 1.2 GB, into `~/.local/share/shev/models`) or uninstall it.
193
+
194
+ The Bonsai pack ships its own loader, because its weights can't be loaded by
195
+ stock `mlx-lm`/`mlx-vlm` (they report `Unsupported model type:
196
+ prism_hadamard_qwen35`). So shev runs the pack's bundled runtime in a resident
197
+ worker, using `uv` with the pack's pinned requirements. Repeated requests in the
198
+ same session reuse the loaded model; a one-shot loader remains as fallback.
199
+ Nothing listens on a port. The first local request
200
+ installs the MLX stack into a `uv` environment, which can take a few minutes.
201
+
202
+ ### Output-head experiments
203
+
204
+ This pack ties its output to `language_model.model.embed_tokens.as_linear`;
205
+ there is no separate `language_model.lm_head`. Its native 2-bit operation
206
+ requires the pack's Hadamard transform. Changing a `bits` parameter alone is
207
+ not a valid conversion.
208
+
209
+ `tools/bench-bonsai-head.py` compares native 2-bit with a correctly repacked
210
+ 4-bit output head **in memory**, leaving input embeddings and installed files
211
+ untouched. Run with the pack's `runtime/requirements.txt`, after a local shev
212
+ request has created `~/.local/share/shev/models/shev_bonsai_worker.py`:
213
+
214
+ ```sh
215
+ uv run --python 3.12 --with-requirements \
216
+ ~/.local/share/shev/models/Ternary-Bonsai-2-2B-mlx-2bit/runtime/requirements.txt \
217
+ python tools/bench-bonsai-head.py
218
+ ```
219
+
220
+ With the current deterministic prompt, one local run measured 1.55 ms/head and
221
+ 669 ms/decision for native 2-bit, versus 2.29 ms/head and 734 ms/decision for
222
+ repacked 4-bit. Both scored 6/6 action labels on a tiny smoke test; an earlier
223
+ prompt/sampled baseline scored 3/6. This is not evidence of general accuracy,
224
+ and the improvement is from the prompt/sampling changes, not from repacking.
225
+ Repacking cannot recover precision already lost in the 2-bit checkpoint.
226
+ Native 2-bit therefore remains the default. Hardware, prompts and output length
227
+ affect these timings; existing explicit provider selections are preserved.
228
+
229
+ ## MCP
230
+
231
+ Shev's MCP server lets **another assistant read your saved decisions**. It does
232
+ not run Bonsai/DeepSeek or edit your files. No API key, OAuth login, terminal,
233
+ network port, or separately started TUI is required: the MCP host starts shev
234
+ as a subprocess and talks JSON-RPC over stdin/stdout.
235
+
236
+ ### 1. Choose the history file
237
+
238
+ Save at least one decision using an explicit file path, for example:
239
+
240
+ ```sh
241
+ shev --file "$HOME/shev-responses.json"
242
+ ```
243
+
244
+ Inside that TUI run **`/mcp install`** (or `/mcp` → install). This writes a
245
+ descriptor under `~/.config/shev/mcp/` and registers the executable and absolute
246
+ history path in an existing global OpenCode config, with a private backup.
247
+ `/mcp status` reports the registration; `/mcp uninstall` removes shev's own
248
+ unchanged registration. It does not delete your decisions.
249
+
250
+ ### 2. Connect OpenCode or Codex
251
+
252
+ For OpenCode, reconnect **shev** from `/mcps` or restart the client after
253
+ installation. Alternatively, register it explicitly from a shell (replace
254
+ the executable path if you built from source):
255
+
256
+ ```sh
257
+ opencode mcp add shev --global -- "$HOME/.local/bin/shev" --mcp --file "$HOME/shev-responses.json"
258
+ opencode mcp list
259
+ ```
260
+
261
+ The equivalent OpenCode V2 configuration is:
262
+
263
+ ```json
264
+ {
265
+ "mcp": {
266
+ "servers": {
267
+ "shev": {
268
+ "type": "local",
269
+ "command": ["/absolute/path/to/shev", "--mcp", "--file", "/absolute/path/to/responses.json"],
270
+ "enabled": true
271
+ }
272
+ }
273
+ }
274
+ }
275
+ ```
276
+
277
+ For Codex, add this to `~/.codex/config.toml` (or your `CODEX_HOME` config),
278
+ replacing the paths, then restart Codex and check `codex mcp list`:
279
+
280
+ ```toml
281
+ [mcp_servers.shev]
282
+ command = "/absolute/path/to/shev"
283
+ args = ["--mcp", "--file", "/absolute/path/to/responses.json"]
284
+ ```
285
+
286
+ Both `shev --mcp` and `shev-cli --mcp` work. For a source build, use
287
+ `/absolute/path/to/repository/target/release/shev` after `cargo build --release`.
288
+ Do not put shell expressions such as `$(pwd)` inside a JSON/TOML command array.
289
+
290
+ ### 3. Ask the host assistant to use shev
291
+
292
+ Example prompts in OpenCode/Codex:
293
+
294
+ - “Use shev's `latest_decision` tool and summarize my most recent decision.”
295
+ - “Use shev's `search_decisions` with query `invoice` and limit `10`.”
296
+ - “Read `response2` using shev's `get_decision` tool.”
297
+
298
+ | Tool | Example arguments | Result |
299
+ | --- | --- | --- |
300
+ | `list_decisions` | `{"limit": 20}` | Most recent records, oldest first |
301
+ | `latest_decision` | `{}` | Latest saved record |
302
+ | `get_decision` | `{"key": "response2"}` or `{"index": 2}` | One saved record |
303
+ | `search_decisions` | `{"query": "invoice", "limit": 10}` | Matching saved decisions |
304
+
305
+ Resources are `shev://decisions` (all records) and
306
+ `shev://decisions/latest` (latest record). Reads use the file afresh, so decisions
307
+ saved by an open TUI become available without restarting the MCP process.
308
+
309
+ **Troubleshooting:** `unknown option --mcp` means the host is launching an old
310
+ TUI binary. Update/rebuild the **exact executable in the MCP command** and
311
+ reconnect shev. Current releases dispatch `--mcp` before terminal setup. If
312
+ connection succeeds but no decisions appear, check that the host and TUI use
313
+ the same absolute history path. Starting `shev --mcp` manually will wait quietly
314
+ for protocol input; this is normal, not a frozen chat window.
315
+
316
+ ### Reuse existing skills and tools
317
+
318
+ `/skills` reads existing `SKILL.md` files from Codex, Claude, shared
319
+ `~/.agents/skills`, `~/skills`, OpenCode's XDG config directory, and ancestor
320
+ project `.opencode`, `.agents`, and `.codex` skill folders, plus local skill
321
+ directories configured in OpenCode. It loads guidance
322
+ into memory; it does not install, edit, or execute skill scripts.
323
+
324
+ `/tools` reads MCP registrations from Codex's `config.toml` and OpenCode's
325
+ global/project JSON or JSONC, including V2 `mcp.servers`. `CODEX_HOME` and
326
+ `XDG_CONFIG_HOME` are respected. Selecting a server connects and lists tools;
327
+ selecting a tool shows its argument schema and prepares `/tool server/tool {}`.
328
+ Edit the arguments, then enter to call it. Successful results become reference
329
+ context for the next decision; `/skills off` unloads them. Supporting context
330
+ does not replace the user's original intent in history.
331
+
332
+ Only tools with `readOnlyHint: true` and without `destructiveHint: true` can
333
+ be called. Unknown/mutating tools are blocked, not silently approved. **MCP
334
+ annotations are declarations from your trusted server, not a security sandbox**;
335
+ only use servers you trust. Starting a configured server can run its startup
336
+ code. Calls have time/output limits and cannot request sampling or approvals.
337
+ Stdio and streamable HTTP (JSON/SSE) are supported. Configured headers and
338
+ environment-based tokens are reused without logging them; host-managed OAuth
339
+ credentials are not copied. An OAuth-only server reports an authentication
340
+ requirement rather than claiming success.
341
+
342
+ The top of the right pane names the loaded skill or successfully called tool
343
+ and its source. Integration identity is also stored with its decision. Merely
344
+ discovering/selecting a server is not reported as a successful tool call.
345
+
346
+ OpenCode's configured JavaScript plugins are listed with compatibility notices.
347
+ **Host-specific plugins cannot run natively in shev**; they require their host
348
+ runtime. Their MCP interfaces, where registered, can be used through `/tools`.
349
+ shev never rewrites host configuration during discovery or tool use. Explicit
350
+ `/mcp install` is separate and backs up configuration before registration.
351
+
352
+ ## CLI
353
+
354
+ The TUI is the friendly front door. The line CLI is `shev-cli` and it's meant
355
+ for pipes:
356
+
357
+ ```sh
358
+ echo "Your invoice is 30 days overdue." | shev-cli -i "draft a polite reminder"
359
+ shev-cli "Should I ship this today?" -i "answer yes or no and why"
360
+ shev-cli --mcp # serve decisions over MCP on stdio
361
+ ```
362
+
363
+ | Option | Meaning |
364
+ | --- | --- |
365
+ | `-c`, `--once <message>` | Judge one message and exit |
366
+ | `-i`, `--intent <text>` | What you want to do with it |
367
+ | `-f`, `--file <path>` | Where decisions are appended (default `responses.json`) |
368
+ | `--mcp` | Serve the recorded decisions over MCP (stdio) |
369
+
370
+ Useful environment variables:
371
+
372
+ | Variable | Meaning |
373
+ | --- | --- |
374
+ | `DEEPSEEK_API_KEY` | Use this key instead of the stored one |
375
+ | `SHEV_RESPONSES_FILE` | Where decisions are appended |
376
+ | `SHEV_INTENT` | Default intent for a non-interactive run |
377
+ | `SHEV_MODELS_DIR` | Where local models live |
378
+ | `SHEV_HOME` | Managed npm state root (set automatically by the npm launcher) |
379
+ | `SHEV_BONSAI_MAX_TOKENS` | Local worker token cap (default `256`; cold fallback `2048`) |
380
+ | `SHEV_BONSAI_STREAM` | `1` enables worker token-delta protocol messages |
381
+ | `SHEV_BONSAI_TEMPERATURE` | Local sampling temperature (default `0`, deterministic) |
382
+
383
+ The footer shows token usage and the last decision's elapsed milliseconds.
384
+ The resident worker reports real local token counts; the cold fallback has no
385
+ usage metadata and reports zero rather than guessing. The concise summary and
386
+ generated response remain alongside the JSON. A measured warm run took about
387
+ 750 ms versus 2500 ms including initial model loading—not a claim of Jev's
388
+ sub-100-ms latency.
389
+ Malformed local decisions receive at most two format-correction retries; usage
390
+ includes those attempts. Retries can add latency and still fail rather than
391
+ silently recording invalid JSON.
392
+
393
+ ## Where things live
394
+
395
+ | Path | What it is |
396
+ | --- | --- |
397
+ | `~/.config/shev/config.json` | API key and the selected model (`0600`) |
398
+ | `responses.json` | The decisions, appended as `response1`, `response2`, … |
399
+ | `~/.local/share/shev/models/` | Downloaded local models |
400
+ | `~/.config/shev/install.json` | Installer-owned binaries/PATH blocks and history paths for scoped cleanup |
401
+
402
+ The npm launcher isolates its config, default history, and models under
403
+ `~/.local/share/shev-npm/state/` (or `$XDG_DATA_HOME/shev-npm/state/`) instead
404
+ of the paths above. This data survives npm upgrades. Shell
405
+ and MCP integrations still read your existing host configuration without
406
+ copying credentials. Explicit `--file`/`SHEV_RESPONSES_FILE` paths stay where you
407
+ chose them and are tracked for explicit `shev --uninstall` cleanup.
408
+
409
+ ## License
410
+
411
+ Apache-2.0. See `LICENSE`.
Binary file
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ require('../scripts/launch.cjs')('shev-cli');
package/bin/shev.cjs ADDED
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ require('../scripts/launch.cjs')('shev');