@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.lock +2050 -0
- package/Cargo.toml +32 -0
- package/LICENSE +201 -0
- package/README.md +429 -2
- package/assets/background.rgb +0 -0
- package/assets/readme/app-decision.png +0 -0
- package/assets/readme/app-home.png +0 -0
- package/assets/readme/hero.jpg +0 -0
- package/bin/shev-cli.cjs +2 -0
- package/bin/shev.cjs +2 -0
- package/install.sh +122 -0
- package/package.json +9 -4
- package/scripts/install.cjs +28 -0
- package/scripts/launch.cjs +64 -0
- package/scripts/launch.test.cjs +56 -0
- package/src/bin/shev.rs +4534 -0
- package/src/installation.rs +390 -0
- package/src/integrations.rs +563 -0
- package/src/lib.rs +3678 -0
- package/src/main.rs +18 -0
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
|
-
|
|
1
|
+

|
|
2
2
|
|
|
3
|
-
|
|
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
|
+

|
|
164
|
+
|
|
165
|
+

|
|
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
|
package/bin/shev-cli.cjs
ADDED