@noorslvt/shev 0.0.0-stage → 0.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.
package/Cargo.toml ADDED
@@ -0,0 +1,32 @@
1
+ [package]
2
+ name = "shev"
3
+ version = "0.2.1"
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,430 @@
1
- # Temporary Holding Version
1
+ ![shev — decisions, without the hype](assets/readme/hero.jpg)
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
+ # shev
4
+
5
+ **A simple Jev-like decision maker. Without the hype.**
6
+
7
+ Hand it one whole message — an email, a ticket, a review, a doc, whatever you
8
+ pasted out of the support queue — and tell it what you want done with it. It
9
+ hands back **one** decision, as JSON:
10
+
11
+ ```json
12
+ {
13
+ "actionable": "Reply to Sam and cc finance about the overdue March invoice.",
14
+ "take_action": true,
15
+ "confidence": 95,
16
+ "generated_response": "Hi Sam, ... (the reply, written out)"
17
+ }
18
+ ```
19
+
20
+ That's the whole thing. No agents. No orchestration. No prompt engineering. No
21
+ five-hundred-token preamble to memorise. One message in, one decision out, in a
22
+ file you can just read.
23
+
24
+ - **Whole message, judged once.** It doesn't chop the thing into paragraphs and
25
+ it doesn't go line by line. One message, one decision.
26
+ - **You say what you want.** It asks before it answers, and what you want done
27
+ is what drives the reply it writes.
28
+ - **The answer has a shape.** `actionable` (a string), `take_action` (a
29
+ boolean), `confidence` (an integer, always in `[34, 100]`). No tuple you have
30
+ to guess at.
31
+ - **Runs on your Mac if you want.** DeepSeek over the network, or a small
32
+ ternary MLX model sitting right there on the machine. Switch whenever.
33
+ - **It writes it all down.** Decisions pile up in `responses.json` as
34
+ `response1`, `response2`, … and other models can read them over MCP.
35
+
36
+ ## Install
37
+
38
+ One line, copy-pasteable:
39
+
40
+ ```sh
41
+ curl -fsSL https://raw.githubusercontent.com/aditauqir/shev/main/install.sh | bash
42
+ ```
43
+
44
+ Then type **`shev`**. The installer uses a user bin directory already on PATH
45
+ where possible. Otherwise it adds a small, removable PATH block to your shell
46
+ profile; open a new terminal and type `shev`—no manual shell edits needed.
47
+
48
+ Prefer npm?
49
+
50
+ ```sh
51
+ npm install -g @noorslvt/shev
52
+ shev
53
+ ```
54
+
55
+ This installs the package **`@noorslvt/shev`**, with the terminal commands
56
+ `shev` and `shev-cli`. The unscoped npm registry name `shev` belongs to an
57
+ unrelated project; **do not use `npm install -g shev`** for this tool. You can
58
+ also install straight from the repo without the registry:
59
+
60
+ ```sh
61
+ npm install -g git+https://github.com/aditauqir/shev.git
62
+ ```
63
+
64
+ Both installers prefer a matching prebuilt release and otherwise build with
65
+ Rust (installing the minimal Rust toolchain if necessary). npm runs a
66
+ `postinstall` step that fetches the right binary or builds it; macOS/Linux are
67
+ supported by the npm launcher, and Windows users can use WSL.
68
+
69
+ Recent npm releases gate install scripts. If your install is skipped, `shev`
70
+ tells you what to run; you can also fix it up front:
71
+
72
+ ```sh
73
+ # if npm blocked the install scripts:
74
+ npm approve-scripts @noorslvt/shev # or:
75
+ npm rebuild -g @noorslvt/shev --foreground-scripts
76
+ ```
77
+
78
+ Got Rust already? Same thing, just as short:
79
+
80
+ ```sh
81
+ cargo install --git https://github.com/aditauqir/shev
82
+ ```
83
+
84
+ ### Uninstall
85
+
86
+ For full cleanup, whether installed with curl or npm, close other running shev
87
+ sessions first:
88
+
89
+ ```sh
90
+ shev --uninstall --dry-run # preview paths; delete nothing
91
+ shev --uninstall # confirm before removal
92
+ # or: shev --uninstall --yes
93
+ ```
94
+
95
+ This removes registered shev binaries, its saved keys/config, local model data,
96
+ tracked chat records, unchanged tracked shev MCP registrations, and the exact PATH
97
+ blocks added by its installer. A full npm-backed uninstall also runs npm's
98
+ package removal. Modified binaries/profile blocks, externally managed weights,
99
+ host recovery backups, unrelated host settings,
100
+ non-chat metadata in export files, source checkouts, and shared tools/caches
101
+ (Rust, Node, uv, Codex, OpenCode) are not deleted.
102
+
103
+ You can also remove the npm package directly:
104
+
105
+ ```sh
106
+ npm uninstall -g @noorslvt/shev
107
+ ```
108
+
109
+ This removes the npm package and its binaries. **Modern npm does not execute
110
+ uninstall hooks**, so it cannot also remove persistent settings/models/history
111
+ or external MCP registrations. Use **`shev --uninstall`** for full cleanup;
112
+ it handles the npm package removal too. Persistent npm data deliberately lives
113
+ outside the package so a normal npm upgrade does not erase private keys,
114
+ history, or model downloads. No background uninstall watchers or npm overrides
115
+ are installed.
116
+
117
+ ## What you need
118
+
119
+ - **Best for local use:** Apple Silicon — **M1 or newer, 16 GB of RAM and up**.
120
+ - **8 GB** will fit the local model too, but it's tight.
121
+ - **Everything else:** runs anywhere with a DeepSeek API key. No Mac required.
122
+
123
+ <sub>Only the local model cares about the Mac. It runs on MLX, and MLX is Apple
124
+ Silicon only, so "run it on your machine" means "run it on a Mac". Point shev at
125
+ a DeepSeek key instead and the work goes over the network — then it builds and
126
+ runs on any platform Rust does.</sub>
127
+
128
+ ## Quick start
129
+
130
+ ```sh
131
+ shev
132
+ ```
133
+
134
+ 1. Bonsai is the default. Install it through `/model` if needed; no API key is
135
+ required. DeepSeek is optional through `/model`; its key is stored at
136
+ `~/.config/shev/config.json` as `0600`.
137
+ 2. Type or paste the whole message. **enter** sends it, **ctrl+j** drops a new
138
+ line in the middle of a multi-line one.
139
+ 3. Say what you want done with it — "draft a short reply", "does this need me
140
+ today", "where's the risk here".
141
+ 4. Read the decision. **enter** starts the next one, or click
142
+ `▸ open responses.json in Finder` and go look at the file.
143
+
144
+ After the first run it's just: run `shev`, type, done.
145
+
146
+ ## The TUI
147
+
148
+ The home/start screen has a white ASCII wordmark directly over the wallpaper,
149
+ without a background box or JSON pane. Once a chat starts, two windows appear:
150
+
151
+ - **Left, the model output.** Every decision as a clean field list. The prompt box sits flush at the
152
+ foot, with its mode line ("Build · bonsai (local) · …") on the last row.
153
+ - **Right, this turn's JSON only.** The raw record for the decision you are on,
154
+ so you can read the file without leaving the screen. Drag across JSON text to
155
+ select it; releasing the mouse copies exactly the selection and shows
156
+ **✓ copied to clipboard** at the top center. The mouse wheel scrolls the JSON
157
+ independently. `/copy json` copies the complete record, including off-screen text.
158
+
159
+ Text panels use **`#0F0E08`** over the dimmed photo wallpaper. Type `/` for commands:
160
+ Panels are inset from the terminal edges. Skills/tools menus show names only;
161
+ long menus scroll around the selected row instead of clipping it off-screen.
162
+
163
+ ![shev home screen](assets/readme/app-home.png)
164
+
165
+ ![shev decision view](assets/readme/app-decision.png)
166
+
167
+ | Command | What it does |
168
+ | --- | --- |
169
+ | `/file <path>` | Load a message from a file (drag-and-drop works too) |
170
+ | `/copy [json]` | Copy selected JSON or the last response; `json` copies the complete record |
171
+ | `/key` | Enter or replace the DeepSeek API key |
172
+ | `/cancel` | Abort the request in flight |
173
+ | `/clear` | Clear the visible chat and input; keep saved history |
174
+ | `/reset` | Confirm clearing the chat, all saved history, loaded context and counters; keep keys/models |
175
+ | `/help` | Show the keybindings |
176
+ | `/model` | Pick the model and manage it (keys, install, uninstall) |
177
+ | `/home` | Back to the home screen (the transcript is kept) |
178
+ | `/history` | Jump through the decisions so far |
179
+ | `/mcp` | Install, remove, or report the local MCP bridge |
180
+ | `/skills` | Load existing skill guidance; `/skills off` clears supporting context |
181
+ | `/tools [server]` | Connect to a registered MCP server and inspect read-only tools |
182
+ | `/tool server/tool <JSON>` | Call a read-only tool and attach its result to the next decision |
183
+ | `/plugins` | Show host-plugin compatibility limits |
184
+ | `/quit` | Leave |
185
+
186
+ Handy keys:
187
+
188
+ | Key | What it does |
189
+ | --- | --- |
190
+ | `enter` | Send the message, then the intent |
191
+ | `ctrl+j` | Newline inside the box |
192
+ | `ctrl+t` | Switch the model (DeepSeek ↔ Bonsai) |
193
+ | `ctrl+h` | Open the history (same as `/history`) |
194
+ | `ctrl+d` in history | Confirm deletion of only the selected saved entry |
195
+ | `ctrl+y` | Copy selected JSON, or the last generated response |
196
+ | `ctrl+c` | Quit |
197
+
198
+ `/clear` starts a fresh chat view; `/history` can reopen retained records.
199
+ `/reset` and history deletion default to **cancel** in their confirmation menus.
200
+ Confirmed changes update the responses file, so MCP clients see them too.
201
+
202
+ ## Models
203
+
204
+ `/model` switches between two backends and manages each one.
205
+
206
+ **DeepSeek** — the secondary, explicitly selected remote option; needs an API key. Options: enter a new
207
+ key, remove the stored key, or cancel.
208
+
209
+ **Bonsai (default)** — `prism-ml/Ternary-Bonsai-2-2B-mlx-2bit`, a small ternary model that
210
+ runs on Apple Silicon through MLX. Options: install it from the internet
211
+ (about 1.2 GB, into `~/.local/share/shev/models`) or uninstall it.
212
+
213
+ The Bonsai pack ships its own loader, because its weights can't be loaded by
214
+ stock `mlx-lm`/`mlx-vlm` (they report `Unsupported model type:
215
+ prism_hadamard_qwen35`). So shev runs the pack's bundled runtime in a resident
216
+ worker, using `uv` with the pack's pinned requirements. Repeated requests in the
217
+ same session reuse the loaded model; a one-shot loader remains as fallback.
218
+ Nothing listens on a port. The first local request
219
+ installs the MLX stack into a `uv` environment, which can take a few minutes.
220
+
221
+ ### Output-head experiments
222
+
223
+ This pack ties its output to `language_model.model.embed_tokens.as_linear`;
224
+ there is no separate `language_model.lm_head`. Its native 2-bit operation
225
+ requires the pack's Hadamard transform. Changing a `bits` parameter alone is
226
+ not a valid conversion.
227
+
228
+ `tools/bench-bonsai-head.py` compares native 2-bit with a correctly repacked
229
+ 4-bit output head **in memory**, leaving input embeddings and installed files
230
+ untouched. Run with the pack's `runtime/requirements.txt`, after a local shev
231
+ request has created `~/.local/share/shev/models/shev_bonsai_worker.py`:
232
+
233
+ ```sh
234
+ uv run --python 3.12 --with-requirements \
235
+ ~/.local/share/shev/models/Ternary-Bonsai-2-2B-mlx-2bit/runtime/requirements.txt \
236
+ python tools/bench-bonsai-head.py
237
+ ```
238
+
239
+ With the current deterministic prompt, one local run measured 1.55 ms/head and
240
+ 669 ms/decision for native 2-bit, versus 2.29 ms/head and 734 ms/decision for
241
+ repacked 4-bit. Both scored 6/6 action labels on a tiny smoke test; an earlier
242
+ prompt/sampled baseline scored 3/6. This is not evidence of general accuracy,
243
+ and the improvement is from the prompt/sampling changes, not from repacking.
244
+ Repacking cannot recover precision already lost in the 2-bit checkpoint.
245
+ Native 2-bit therefore remains the default. Hardware, prompts and output length
246
+ affect these timings; existing explicit provider selections are preserved.
247
+
248
+ ## MCP
249
+
250
+ Shev's MCP server lets **another assistant read your saved decisions**. It does
251
+ not run Bonsai/DeepSeek or edit your files. No API key, OAuth login, terminal,
252
+ network port, or separately started TUI is required: the MCP host starts shev
253
+ as a subprocess and talks JSON-RPC over stdin/stdout.
254
+
255
+ ### 1. Choose the history file
256
+
257
+ Save at least one decision using an explicit file path, for example:
258
+
259
+ ```sh
260
+ shev --file "$HOME/shev-responses.json"
261
+ ```
262
+
263
+ Inside that TUI run **`/mcp install`** (or `/mcp` → install). This writes a
264
+ descriptor under `~/.config/shev/mcp/` and registers the executable and absolute
265
+ history path in an existing global OpenCode config, with a private backup.
266
+ `/mcp status` reports the registration; `/mcp uninstall` removes shev's own
267
+ unchanged registration. It does not delete your decisions.
268
+
269
+ ### 2. Connect OpenCode or Codex
270
+
271
+ For OpenCode, reconnect **shev** from `/mcps` or restart the client after
272
+ installation. Alternatively, register it explicitly from a shell (replace
273
+ the executable path if you built from source):
274
+
275
+ ```sh
276
+ opencode mcp add shev --global -- "$HOME/.local/bin/shev" --mcp --file "$HOME/shev-responses.json"
277
+ opencode mcp list
278
+ ```
279
+
280
+ The equivalent OpenCode V2 configuration is:
281
+
282
+ ```json
283
+ {
284
+ "mcp": {
285
+ "servers": {
286
+ "shev": {
287
+ "type": "local",
288
+ "command": ["/absolute/path/to/shev", "--mcp", "--file", "/absolute/path/to/responses.json"],
289
+ "enabled": true
290
+ }
291
+ }
292
+ }
293
+ }
294
+ ```
295
+
296
+ For Codex, add this to `~/.codex/config.toml` (or your `CODEX_HOME` config),
297
+ replacing the paths, then restart Codex and check `codex mcp list`:
298
+
299
+ ```toml
300
+ [mcp_servers.shev]
301
+ command = "/absolute/path/to/shev"
302
+ args = ["--mcp", "--file", "/absolute/path/to/responses.json"]
303
+ ```
304
+
305
+ Both `shev --mcp` and `shev-cli --mcp` work. For a source build, use
306
+ `/absolute/path/to/repository/target/release/shev` after `cargo build --release`.
307
+ Do not put shell expressions such as `$(pwd)` inside a JSON/TOML command array.
308
+
309
+ ### 3. Ask the host assistant to use shev
310
+
311
+ Example prompts in OpenCode/Codex:
312
+
313
+ - “Use shev's `latest_decision` tool and summarize my most recent decision.”
314
+ - “Use shev's `search_decisions` with query `invoice` and limit `10`.”
315
+ - “Read `response2` using shev's `get_decision` tool.”
316
+
317
+ | Tool | Example arguments | Result |
318
+ | --- | --- | --- |
319
+ | `list_decisions` | `{"limit": 20}` | Most recent records, oldest first |
320
+ | `latest_decision` | `{}` | Latest saved record |
321
+ | `get_decision` | `{"key": "response2"}` or `{"index": 2}` | One saved record |
322
+ | `search_decisions` | `{"query": "invoice", "limit": 10}` | Matching saved decisions |
323
+
324
+ Resources are `shev://decisions` (all records) and
325
+ `shev://decisions/latest` (latest record). Reads use the file afresh, so decisions
326
+ saved by an open TUI become available without restarting the MCP process.
327
+
328
+ **Troubleshooting:** `unknown option --mcp` means the host is launching an old
329
+ TUI binary. Update/rebuild the **exact executable in the MCP command** and
330
+ reconnect shev. Current releases dispatch `--mcp` before terminal setup. If
331
+ connection succeeds but no decisions appear, check that the host and TUI use
332
+ the same absolute history path. Starting `shev --mcp` manually will wait quietly
333
+ for protocol input; this is normal, not a frozen chat window.
334
+
335
+ ### Reuse existing skills and tools
336
+
337
+ `/skills` reads existing `SKILL.md` files from Codex, Claude, shared
338
+ `~/.agents/skills`, `~/skills`, OpenCode's XDG config directory, and ancestor
339
+ project `.opencode`, `.agents`, and `.codex` skill folders, plus local skill
340
+ directories configured in OpenCode. It loads guidance
341
+ into memory; it does not install, edit, or execute skill scripts.
342
+
343
+ `/tools` reads MCP registrations from Codex's `config.toml` and OpenCode's
344
+ global/project JSON or JSONC, including V2 `mcp.servers`. `CODEX_HOME` and
345
+ `XDG_CONFIG_HOME` are respected. Selecting a server connects and lists tools;
346
+ selecting a tool shows its argument schema and prepares `/tool server/tool {}`.
347
+ Edit the arguments, then enter to call it. Successful results become reference
348
+ context for the next decision; `/skills off` unloads them. Supporting context
349
+ does not replace the user's original intent in history.
350
+
351
+ Only tools with `readOnlyHint: true` and without `destructiveHint: true` can
352
+ be called. Unknown/mutating tools are blocked, not silently approved. **MCP
353
+ annotations are declarations from your trusted server, not a security sandbox**;
354
+ only use servers you trust. Starting a configured server can run its startup
355
+ code. Calls have time/output limits and cannot request sampling or approvals.
356
+ Stdio and streamable HTTP (JSON/SSE) are supported. Configured headers and
357
+ environment-based tokens are reused without logging them; host-managed OAuth
358
+ credentials are not copied. An OAuth-only server reports an authentication
359
+ requirement rather than claiming success.
360
+
361
+ The top of the right pane names the loaded skill or successfully called tool
362
+ and its source. Integration identity is also stored with its decision. Merely
363
+ discovering/selecting a server is not reported as a successful tool call.
364
+
365
+ OpenCode's configured JavaScript plugins are listed with compatibility notices.
366
+ **Host-specific plugins cannot run natively in shev**; they require their host
367
+ runtime. Their MCP interfaces, where registered, can be used through `/tools`.
368
+ shev never rewrites host configuration during discovery or tool use. Explicit
369
+ `/mcp install` is separate and backs up configuration before registration.
370
+
371
+ ## CLI
372
+
373
+ The TUI is the friendly front door. The line CLI is `shev-cli` and it's meant
374
+ for pipes:
375
+
376
+ ```sh
377
+ echo "Your invoice is 30 days overdue." | shev-cli -i "draft a polite reminder"
378
+ shev-cli "Should I ship this today?" -i "answer yes or no and why"
379
+ shev-cli --mcp # serve decisions over MCP on stdio
380
+ ```
381
+
382
+ | Option | Meaning |
383
+ | --- | --- |
384
+ | `-c`, `--once <message>` | Judge one message and exit |
385
+ | `-i`, `--intent <text>` | What you want to do with it |
386
+ | `-f`, `--file <path>` | Where decisions are appended (default `responses.json`) |
387
+ | `--mcp` | Serve the recorded decisions over MCP (stdio) |
388
+
389
+ Useful environment variables:
390
+
391
+ | Variable | Meaning |
392
+ | --- | --- |
393
+ | `DEEPSEEK_API_KEY` | Use this key instead of the stored one |
394
+ | `SHEV_RESPONSES_FILE` | Where decisions are appended |
395
+ | `SHEV_INTENT` | Default intent for a non-interactive run |
396
+ | `SHEV_MODELS_DIR` | Where local models live |
397
+ | `SHEV_HOME` | Managed npm state root (set automatically by the npm launcher) |
398
+ | `SHEV_BONSAI_MAX_TOKENS` | Local worker token cap (default `256`; cold fallback `2048`) |
399
+ | `SHEV_BONSAI_STREAM` | `1` enables worker token-delta protocol messages |
400
+ | `SHEV_BONSAI_TEMPERATURE` | Local sampling temperature (default `0`, deterministic) |
401
+
402
+ The footer shows token usage and the last decision's elapsed milliseconds.
403
+ The resident worker reports real local token counts; the cold fallback has no
404
+ usage metadata and reports zero rather than guessing. The concise summary and
405
+ generated response remain alongside the JSON. A measured warm run took about
406
+ 750 ms versus 2500 ms including initial model loading—not a claim of Jev's
407
+ sub-100-ms latency.
408
+ Malformed local decisions receive at most two format-correction retries; usage
409
+ includes those attempts. Retries can add latency and still fail rather than
410
+ silently recording invalid JSON.
411
+
412
+ ## Where things live
413
+
414
+ | Path | What it is |
415
+ | --- | --- |
416
+ | `~/.config/shev/config.json` | API key and the selected model (`0600`) |
417
+ | `responses.json` | The decisions, appended as `response1`, `response2`, … |
418
+ | `~/.local/share/shev/models/` | Downloaded local models |
419
+ | `~/.config/shev/install.json` | Installer-owned binaries/PATH blocks and history paths for scoped cleanup |
420
+
421
+ The npm launcher isolates its config, default history, and models under
422
+ `~/.local/share/shev-npm/state/` (or `$XDG_DATA_HOME/shev-npm/state/`) instead
423
+ of the paths above. This data survives npm upgrades. Shell
424
+ and MCP integrations still read your existing host configuration without
425
+ copying credentials. Explicit `--file`/`SHEV_RESPONSES_FILE` paths stay where you
426
+ chose them and are tracked for explicit `shev --uninstall` cleanup.
427
+
428
+ ## License
429
+
430
+ Apache-2.0. See `LICENSE`.
Binary file
Binary file
Binary file
Binary file
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ require('../scripts/launch.cjs')('shev-cli');