jev-cli 0.4.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- jev_cli-0.4.1/LICENSE +21 -0
- jev_cli-0.4.1/PKG-INFO +302 -0
- jev_cli-0.4.1/README.md +284 -0
- jev_cli-0.4.1/pyproject.toml +32 -0
- jev_cli-0.4.1/scripts/embed_skills.py +22 -0
- jev_cli-0.4.1/skills/jev-cli/SKILL.md +61 -0
- jev_cli-0.4.1/skills/jev-cli/references/cli.md +142 -0
- jev_cli-0.4.1/src/jev_cli/__init__.py +288 -0
- jev_cli-0.4.1/src/jev_cli/bundled_skills/jev-cli/SKILL.md +61 -0
- jev_cli-0.4.1/src/jev_cli/bundled_skills/jev-cli/references/cli.md +142 -0
- jev_cli-0.4.1/src/jev_cli/py.typed +0 -0
- jev_cli-0.4.1/tests/test_jev.py +197 -0
- jev_cli-0.4.1/tests/test_skill.py +25 -0
jev_cli-0.4.1/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 tumf
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
jev_cli-0.4.1/PKG-INFO
ADDED
|
@@ -0,0 +1,302 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: jev-cli
|
|
3
|
+
Version: 0.4.1
|
|
4
|
+
Summary: Small dependency-free CLI for TypeSafe Jev
|
|
5
|
+
Keywords: typesafe,jev,cli,ai
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
License-File: LICENSE
|
|
8
|
+
Classifier: Development Status :: 3 - Alpha
|
|
9
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
10
|
+
Classifier: Programming Language :: Python :: 3
|
|
11
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
12
|
+
Classifier: Typing :: Typed
|
|
13
|
+
Requires-Python: >=3.13
|
|
14
|
+
Project-URL: Homepage, https://github.com/tumf/jev-cli
|
|
15
|
+
Project-URL: Issues, https://github.com/tumf/jev-cli/issues
|
|
16
|
+
Project-URL: Repository, https://github.com/tumf/jev-cli
|
|
17
|
+
Description-Content-Type: text/markdown
|
|
18
|
+
|
|
19
|
+
# jev-cli
|
|
20
|
+
|
|
21
|
+
A small, dependency-free CLI for [TypeSafe Jev](https://docs.typesafe.ai/introduction). Send text or JSON state, ask typed questions, and receive machine-readable `noul`, `choice`, or `score` answers.
|
|
22
|
+
|
|
23
|
+
The `jev` command is useful when application code needs a fast classification or judgment instead of generated prose.
|
|
24
|
+
|
|
25
|
+
> **Unofficial:** This is an independent community project. It is not affiliated with, maintained by, or endorsed by TypeSafe AI.
|
|
26
|
+
|
|
27
|
+
## Features
|
|
28
|
+
|
|
29
|
+
- Supports all three Jev primitives: `noul`, `choice`, and `score`
|
|
30
|
+
- Sends multiple questions in one request with `run`
|
|
31
|
+
- Accepts text, JSON, files, and stdin
|
|
32
|
+
- Emits compact JSON by default
|
|
33
|
+
- Can print only the primary value for shell scripts
|
|
34
|
+
- Uses structured stderr errors and meaningful exit codes
|
|
35
|
+
- Has no runtime dependencies outside Python's standard library
|
|
36
|
+
|
|
37
|
+
## Requirements
|
|
38
|
+
|
|
39
|
+
- Python 3.13 or later
|
|
40
|
+
- [uv](https://docs.astral.sh/uv/)
|
|
41
|
+
- GNU Make
|
|
42
|
+
- A TypeSafe API key
|
|
43
|
+
|
|
44
|
+
## Install
|
|
45
|
+
|
|
46
|
+
Clone the repository and install the command with `uv tool` through the Makefile. This installs `jev` into uv's executable directory and verifies the installed version.
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
git clone https://github.com/tumf/jev-cli.git
|
|
50
|
+
cd jev-cli
|
|
51
|
+
make install
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
Verify that the command is available:
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
jev --version
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
Expected output:
|
|
61
|
+
|
|
62
|
+
```text
|
|
63
|
+
jev 0.4.1
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
## Authentication
|
|
67
|
+
|
|
68
|
+
The recommended approach for automation is the `TYPESAFE_API_KEY` environment variable. It takes precedence over the credential file.
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
export TYPESAFE_API_KEY='your-api-key'
|
|
72
|
+
jev auth status
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
For local use, enter the key at the hidden prompt. `auth set` does not accept the key as a command-line argument, which keeps it out of process arguments and shell history.
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
jev auth set
|
|
79
|
+
jev auth status
|
|
80
|
+
jev auth test
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
For non-interactive automation, piping the key to `jev auth set` remains supported.
|
|
84
|
+
|
|
85
|
+
`auth status` reports only whether a key is available. `auth test` sends a minimal request to Jev and verifies that the key is accepted. Neither command prints the key.
|
|
86
|
+
|
|
87
|
+
The fallback credential path follows XDG conventions:
|
|
88
|
+
|
|
89
|
+
- `$XDG_CONFIG_HOME/jev-cli/credentials.json` when `XDG_CONFIG_HOME` is set
|
|
90
|
+
- `~/.config/jev-cli/credentials.json` otherwise
|
|
91
|
+
|
|
92
|
+
The credential directory is created with mode `0700`; the file is written atomically with mode `0600`.
|
|
93
|
+
|
|
94
|
+
## Quick start
|
|
95
|
+
|
|
96
|
+
`--question` and `--state` also accept the short forms `-q` and `-s`. `--value` has no short form.
|
|
97
|
+
|
|
98
|
+
## Install the bundled Agent Skill
|
|
99
|
+
|
|
100
|
+
`jev-cli` currently bundles the `jev-cli` skill. Install it for the current project or globally:
|
|
101
|
+
|
|
102
|
+
```bash
|
|
103
|
+
jev install-skills
|
|
104
|
+
jev install-skills --global
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
Use `--claude` to target Claude's skill directory instead:
|
|
108
|
+
|
|
109
|
+
```bash
|
|
110
|
+
jev install-skills --claude
|
|
111
|
+
jev install-skills --global --claude
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
The command prints JSON. It refreshes only copies it previously installed and refuses to overwrite an unmanaged skill directory.
|
|
115
|
+
|
|
116
|
+
Ask whether a message expresses urgency. `--value` prints only the resulting probability from `0` to `1`.
|
|
117
|
+
|
|
118
|
+
```bash
|
|
119
|
+
jev noul \
|
|
120
|
+
--question 'Does this message express urgency?' \
|
|
121
|
+
--state 'Please restore service today.' \
|
|
122
|
+
--value
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
Example output:
|
|
126
|
+
|
|
127
|
+
```text
|
|
128
|
+
0.98
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
Without `--value`, the command returns the complete API response as JSON, including model and token usage.
|
|
132
|
+
|
|
133
|
+
```bash
|
|
134
|
+
jev noul \
|
|
135
|
+
--question 'Does this message express urgency?' \
|
|
136
|
+
--state 'Please restore service today.' \
|
|
137
|
+
--pretty
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
## Question types
|
|
141
|
+
|
|
142
|
+
### Noul: yes/no probability
|
|
143
|
+
|
|
144
|
+
Use `noul` for one focused yes/no judgment. The value is the probability that the answer is yes.
|
|
145
|
+
|
|
146
|
+
```bash
|
|
147
|
+
jev noul \
|
|
148
|
+
--question 'Does this message request a refund?' \
|
|
149
|
+
--state 'The integration is broken, but I do not want a refund.' \
|
|
150
|
+
--value
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
### Choice: select one option
|
|
154
|
+
|
|
155
|
+
Use `choice` when the answer must be one of a known set. Each option uses `KEY=DESCRIPTION` syntax.
|
|
156
|
+
|
|
157
|
+
```bash
|
|
158
|
+
jev choice \
|
|
159
|
+
--question 'Which team should handle this?' \
|
|
160
|
+
--state 'The payment integration keeps failing.' \
|
|
161
|
+
-o 'billing=Payment, charge, or refund issues' \
|
|
162
|
+
-o 'technical=Bugs or integration failures' \
|
|
163
|
+
-o 'other=None of these' \
|
|
164
|
+
--pretty
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
### Score: evaluate ordered levels
|
|
168
|
+
|
|
169
|
+
Use `score` for an ordered scale. Levels are numbered from zero in the order supplied.
|
|
170
|
+
|
|
171
|
+
```bash
|
|
172
|
+
jev score \
|
|
173
|
+
--question 'How frustrated is the customer?' \
|
|
174
|
+
--state 'This has failed for three days. Please help.' \
|
|
175
|
+
-l 'Calm' \
|
|
176
|
+
-l 'Concerned but civil' \
|
|
177
|
+
-l 'Very angry' \
|
|
178
|
+
--value
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
## Input formats
|
|
182
|
+
|
|
183
|
+
### Standard input
|
|
184
|
+
|
|
185
|
+
Omit the state or pass `-` to read it from stdin. This is useful for pipelines and avoids putting sensitive input in shell history.
|
|
186
|
+
|
|
187
|
+
```bash
|
|
188
|
+
printf '%s' 'Please resolve this today.' | \
|
|
189
|
+
jev noul --question 'Does this message express urgency?' --value
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
### File input
|
|
193
|
+
|
|
194
|
+
Prefix a path with `@` to read its contents.
|
|
195
|
+
|
|
196
|
+
```bash
|
|
197
|
+
jev noul \
|
|
198
|
+
--question 'Does this document mention security risks?' \
|
|
199
|
+
--state @document.txt \
|
|
200
|
+
--value
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
### JSON state
|
|
204
|
+
|
|
205
|
+
Use `--json-state` to parse the state as JSON. Instructions can refer to named fields.
|
|
206
|
+
|
|
207
|
+
```bash
|
|
208
|
+
printf '%s' '{"message":"Please respond today"}' | \
|
|
209
|
+
jev noul \
|
|
210
|
+
--question 'Does `message` express urgency?' \
|
|
211
|
+
--json-state \
|
|
212
|
+
--value
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
## Batch questions
|
|
216
|
+
|
|
217
|
+
Jev evaluates questions independently against the same state. Use `run` to send a complete System One request and avoid one API call per question.
|
|
218
|
+
|
|
219
|
+
Create `request.json`:
|
|
220
|
+
|
|
221
|
+
```json
|
|
222
|
+
{
|
|
223
|
+
"state": {
|
|
224
|
+
"message": "The payment integration has failed for three days. Please fix it today."
|
|
225
|
+
},
|
|
226
|
+
"model": "jev-latest",
|
|
227
|
+
"questions": {
|
|
228
|
+
"department": {
|
|
229
|
+
"type": "choice",
|
|
230
|
+
"instructions": "Which team should handle `message`?",
|
|
231
|
+
"criteria": {
|
|
232
|
+
"billing": "Payment, charge, or refund issues",
|
|
233
|
+
"technical": "Bugs or integration failures",
|
|
234
|
+
"other": "None of these"
|
|
235
|
+
}
|
|
236
|
+
},
|
|
237
|
+
"urgent": {
|
|
238
|
+
"type": "noul",
|
|
239
|
+
"instructions": "Does `message` express urgency?"
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
Send it in one request:
|
|
246
|
+
|
|
247
|
+
```bash
|
|
248
|
+
jev run request.json --pretty
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
A request can also be piped through stdin:
|
|
252
|
+
|
|
253
|
+
```bash
|
|
254
|
+
cat request.json | jev run - --pretty
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
## Output and automation
|
|
258
|
+
|
|
259
|
+
The default stdout is one JSON object. Logs and structured errors go to stderr, so stdout can be piped directly into another program.
|
|
260
|
+
|
|
261
|
+
Use `--value` with `noul`, `choice`, or `score` when a script needs only the primary answer:
|
|
262
|
+
|
|
263
|
+
```bash
|
|
264
|
+
if awk 'BEGIN { exit !(ARGV[1] >= 0.9) }' \
|
|
265
|
+
"$(jev noul --question 'Is this urgent?' --state 'Restore service today.' --value)"; then
|
|
266
|
+
echo urgent
|
|
267
|
+
fi
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
Use `--model` to select another model available to the account:
|
|
271
|
+
|
|
272
|
+
```bash
|
|
273
|
+
jev noul --question 'Is this urgent?' --state 'Restore service today.' \
|
|
274
|
+
--model jev-latest \
|
|
275
|
+
--pretty
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
## Exit codes
|
|
279
|
+
|
|
280
|
+
| Code | Meaning |
|
|
281
|
+
|---:|---|
|
|
282
|
+
| `0` | Success |
|
|
283
|
+
| `1` | Unexpected API response or other error |
|
|
284
|
+
| `2` | Invalid arguments or input |
|
|
285
|
+
| `3` | Missing or rejected authentication |
|
|
286
|
+
| `4` | Connection, rate-limit, or transient server error |
|
|
287
|
+
|
|
288
|
+
An error is emitted as JSON on stderr:
|
|
289
|
+
|
|
290
|
+
```json
|
|
291
|
+
{"ok": false, "error": "TypeSafe API key is not stored; run: jev auth set"}
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
## Scope and limitations
|
|
295
|
+
|
|
296
|
+
The `jev` command is a thin client for focused System One judgments. It does not generate prose, perform arithmetic, compare dates, or replace application-level validation. Keep deterministic work in code and use Jev for semantic judgments.
|
|
297
|
+
|
|
298
|
+
The CLI sends the supplied state and questions to the TypeSafe API. Do not submit data that your organization is not permitted to send to that service.
|
|
299
|
+
|
|
300
|
+
## License
|
|
301
|
+
|
|
302
|
+
[MIT](LICENSE)
|
jev_cli-0.4.1/README.md
ADDED
|
@@ -0,0 +1,284 @@
|
|
|
1
|
+
# jev-cli
|
|
2
|
+
|
|
3
|
+
A small, dependency-free CLI for [TypeSafe Jev](https://docs.typesafe.ai/introduction). Send text or JSON state, ask typed questions, and receive machine-readable `noul`, `choice`, or `score` answers.
|
|
4
|
+
|
|
5
|
+
The `jev` command is useful when application code needs a fast classification or judgment instead of generated prose.
|
|
6
|
+
|
|
7
|
+
> **Unofficial:** This is an independent community project. It is not affiliated with, maintained by, or endorsed by TypeSafe AI.
|
|
8
|
+
|
|
9
|
+
## Features
|
|
10
|
+
|
|
11
|
+
- Supports all three Jev primitives: `noul`, `choice`, and `score`
|
|
12
|
+
- Sends multiple questions in one request with `run`
|
|
13
|
+
- Accepts text, JSON, files, and stdin
|
|
14
|
+
- Emits compact JSON by default
|
|
15
|
+
- Can print only the primary value for shell scripts
|
|
16
|
+
- Uses structured stderr errors and meaningful exit codes
|
|
17
|
+
- Has no runtime dependencies outside Python's standard library
|
|
18
|
+
|
|
19
|
+
## Requirements
|
|
20
|
+
|
|
21
|
+
- Python 3.13 or later
|
|
22
|
+
- [uv](https://docs.astral.sh/uv/)
|
|
23
|
+
- GNU Make
|
|
24
|
+
- A TypeSafe API key
|
|
25
|
+
|
|
26
|
+
## Install
|
|
27
|
+
|
|
28
|
+
Clone the repository and install the command with `uv tool` through the Makefile. This installs `jev` into uv's executable directory and verifies the installed version.
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
git clone https://github.com/tumf/jev-cli.git
|
|
32
|
+
cd jev-cli
|
|
33
|
+
make install
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
Verify that the command is available:
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
jev --version
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
Expected output:
|
|
43
|
+
|
|
44
|
+
```text
|
|
45
|
+
jev 0.4.1
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## Authentication
|
|
49
|
+
|
|
50
|
+
The recommended approach for automation is the `TYPESAFE_API_KEY` environment variable. It takes precedence over the credential file.
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
export TYPESAFE_API_KEY='your-api-key'
|
|
54
|
+
jev auth status
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
For local use, enter the key at the hidden prompt. `auth set` does not accept the key as a command-line argument, which keeps it out of process arguments and shell history.
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
jev auth set
|
|
61
|
+
jev auth status
|
|
62
|
+
jev auth test
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
For non-interactive automation, piping the key to `jev auth set` remains supported.
|
|
66
|
+
|
|
67
|
+
`auth status` reports only whether a key is available. `auth test` sends a minimal request to Jev and verifies that the key is accepted. Neither command prints the key.
|
|
68
|
+
|
|
69
|
+
The fallback credential path follows XDG conventions:
|
|
70
|
+
|
|
71
|
+
- `$XDG_CONFIG_HOME/jev-cli/credentials.json` when `XDG_CONFIG_HOME` is set
|
|
72
|
+
- `~/.config/jev-cli/credentials.json` otherwise
|
|
73
|
+
|
|
74
|
+
The credential directory is created with mode `0700`; the file is written atomically with mode `0600`.
|
|
75
|
+
|
|
76
|
+
## Quick start
|
|
77
|
+
|
|
78
|
+
`--question` and `--state` also accept the short forms `-q` and `-s`. `--value` has no short form.
|
|
79
|
+
|
|
80
|
+
## Install the bundled Agent Skill
|
|
81
|
+
|
|
82
|
+
`jev-cli` currently bundles the `jev-cli` skill. Install it for the current project or globally:
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
jev install-skills
|
|
86
|
+
jev install-skills --global
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
Use `--claude` to target Claude's skill directory instead:
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
jev install-skills --claude
|
|
93
|
+
jev install-skills --global --claude
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
The command prints JSON. It refreshes only copies it previously installed and refuses to overwrite an unmanaged skill directory.
|
|
97
|
+
|
|
98
|
+
Ask whether a message expresses urgency. `--value` prints only the resulting probability from `0` to `1`.
|
|
99
|
+
|
|
100
|
+
```bash
|
|
101
|
+
jev noul \
|
|
102
|
+
--question 'Does this message express urgency?' \
|
|
103
|
+
--state 'Please restore service today.' \
|
|
104
|
+
--value
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
Example output:
|
|
108
|
+
|
|
109
|
+
```text
|
|
110
|
+
0.98
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
Without `--value`, the command returns the complete API response as JSON, including model and token usage.
|
|
114
|
+
|
|
115
|
+
```bash
|
|
116
|
+
jev noul \
|
|
117
|
+
--question 'Does this message express urgency?' \
|
|
118
|
+
--state 'Please restore service today.' \
|
|
119
|
+
--pretty
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
## Question types
|
|
123
|
+
|
|
124
|
+
### Noul: yes/no probability
|
|
125
|
+
|
|
126
|
+
Use `noul` for one focused yes/no judgment. The value is the probability that the answer is yes.
|
|
127
|
+
|
|
128
|
+
```bash
|
|
129
|
+
jev noul \
|
|
130
|
+
--question 'Does this message request a refund?' \
|
|
131
|
+
--state 'The integration is broken, but I do not want a refund.' \
|
|
132
|
+
--value
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
### Choice: select one option
|
|
136
|
+
|
|
137
|
+
Use `choice` when the answer must be one of a known set. Each option uses `KEY=DESCRIPTION` syntax.
|
|
138
|
+
|
|
139
|
+
```bash
|
|
140
|
+
jev choice \
|
|
141
|
+
--question 'Which team should handle this?' \
|
|
142
|
+
--state 'The payment integration keeps failing.' \
|
|
143
|
+
-o 'billing=Payment, charge, or refund issues' \
|
|
144
|
+
-o 'technical=Bugs or integration failures' \
|
|
145
|
+
-o 'other=None of these' \
|
|
146
|
+
--pretty
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
### Score: evaluate ordered levels
|
|
150
|
+
|
|
151
|
+
Use `score` for an ordered scale. Levels are numbered from zero in the order supplied.
|
|
152
|
+
|
|
153
|
+
```bash
|
|
154
|
+
jev score \
|
|
155
|
+
--question 'How frustrated is the customer?' \
|
|
156
|
+
--state 'This has failed for three days. Please help.' \
|
|
157
|
+
-l 'Calm' \
|
|
158
|
+
-l 'Concerned but civil' \
|
|
159
|
+
-l 'Very angry' \
|
|
160
|
+
--value
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
## Input formats
|
|
164
|
+
|
|
165
|
+
### Standard input
|
|
166
|
+
|
|
167
|
+
Omit the state or pass `-` to read it from stdin. This is useful for pipelines and avoids putting sensitive input in shell history.
|
|
168
|
+
|
|
169
|
+
```bash
|
|
170
|
+
printf '%s' 'Please resolve this today.' | \
|
|
171
|
+
jev noul --question 'Does this message express urgency?' --value
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
### File input
|
|
175
|
+
|
|
176
|
+
Prefix a path with `@` to read its contents.
|
|
177
|
+
|
|
178
|
+
```bash
|
|
179
|
+
jev noul \
|
|
180
|
+
--question 'Does this document mention security risks?' \
|
|
181
|
+
--state @document.txt \
|
|
182
|
+
--value
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
### JSON state
|
|
186
|
+
|
|
187
|
+
Use `--json-state` to parse the state as JSON. Instructions can refer to named fields.
|
|
188
|
+
|
|
189
|
+
```bash
|
|
190
|
+
printf '%s' '{"message":"Please respond today"}' | \
|
|
191
|
+
jev noul \
|
|
192
|
+
--question 'Does `message` express urgency?' \
|
|
193
|
+
--json-state \
|
|
194
|
+
--value
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
## Batch questions
|
|
198
|
+
|
|
199
|
+
Jev evaluates questions independently against the same state. Use `run` to send a complete System One request and avoid one API call per question.
|
|
200
|
+
|
|
201
|
+
Create `request.json`:
|
|
202
|
+
|
|
203
|
+
```json
|
|
204
|
+
{
|
|
205
|
+
"state": {
|
|
206
|
+
"message": "The payment integration has failed for three days. Please fix it today."
|
|
207
|
+
},
|
|
208
|
+
"model": "jev-latest",
|
|
209
|
+
"questions": {
|
|
210
|
+
"department": {
|
|
211
|
+
"type": "choice",
|
|
212
|
+
"instructions": "Which team should handle `message`?",
|
|
213
|
+
"criteria": {
|
|
214
|
+
"billing": "Payment, charge, or refund issues",
|
|
215
|
+
"technical": "Bugs or integration failures",
|
|
216
|
+
"other": "None of these"
|
|
217
|
+
}
|
|
218
|
+
},
|
|
219
|
+
"urgent": {
|
|
220
|
+
"type": "noul",
|
|
221
|
+
"instructions": "Does `message` express urgency?"
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
Send it in one request:
|
|
228
|
+
|
|
229
|
+
```bash
|
|
230
|
+
jev run request.json --pretty
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
A request can also be piped through stdin:
|
|
234
|
+
|
|
235
|
+
```bash
|
|
236
|
+
cat request.json | jev run - --pretty
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
## Output and automation
|
|
240
|
+
|
|
241
|
+
The default stdout is one JSON object. Logs and structured errors go to stderr, so stdout can be piped directly into another program.
|
|
242
|
+
|
|
243
|
+
Use `--value` with `noul`, `choice`, or `score` when a script needs only the primary answer:
|
|
244
|
+
|
|
245
|
+
```bash
|
|
246
|
+
if awk 'BEGIN { exit !(ARGV[1] >= 0.9) }' \
|
|
247
|
+
"$(jev noul --question 'Is this urgent?' --state 'Restore service today.' --value)"; then
|
|
248
|
+
echo urgent
|
|
249
|
+
fi
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
Use `--model` to select another model available to the account:
|
|
253
|
+
|
|
254
|
+
```bash
|
|
255
|
+
jev noul --question 'Is this urgent?' --state 'Restore service today.' \
|
|
256
|
+
--model jev-latest \
|
|
257
|
+
--pretty
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
## Exit codes
|
|
261
|
+
|
|
262
|
+
| Code | Meaning |
|
|
263
|
+
|---:|---|
|
|
264
|
+
| `0` | Success |
|
|
265
|
+
| `1` | Unexpected API response or other error |
|
|
266
|
+
| `2` | Invalid arguments or input |
|
|
267
|
+
| `3` | Missing or rejected authentication |
|
|
268
|
+
| `4` | Connection, rate-limit, or transient server error |
|
|
269
|
+
|
|
270
|
+
An error is emitted as JSON on stderr:
|
|
271
|
+
|
|
272
|
+
```json
|
|
273
|
+
{"ok": false, "error": "TypeSafe API key is not stored; run: jev auth set"}
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
## Scope and limitations
|
|
277
|
+
|
|
278
|
+
The `jev` command is a thin client for focused System One judgments. It does not generate prose, perform arithmetic, compare dates, or replace application-level validation. Keep deterministic work in code and use Jev for semantic judgments.
|
|
279
|
+
|
|
280
|
+
The CLI sends the supplied state and questions to the TypeSafe API. Do not submit data that your organization is not permitted to send to that service.
|
|
281
|
+
|
|
282
|
+
## License
|
|
283
|
+
|
|
284
|
+
[MIT](LICENSE)
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "jev-cli"
|
|
3
|
+
version = "0.4.1"
|
|
4
|
+
description = "Small dependency-free CLI for TypeSafe Jev"
|
|
5
|
+
readme = "README.md"
|
|
6
|
+
license = "MIT"
|
|
7
|
+
license-files = ["LICENSE"]
|
|
8
|
+
requires-python = ">=3.13"
|
|
9
|
+
dependencies = []
|
|
10
|
+
keywords = ["typesafe", "jev", "cli", "ai"]
|
|
11
|
+
classifiers = [
|
|
12
|
+
"Development Status :: 3 - Alpha",
|
|
13
|
+
"License :: OSI Approved :: MIT License",
|
|
14
|
+
"Programming Language :: Python :: 3",
|
|
15
|
+
"Programming Language :: Python :: 3.13",
|
|
16
|
+
"Typing :: Typed",
|
|
17
|
+
]
|
|
18
|
+
|
|
19
|
+
[project.urls]
|
|
20
|
+
Homepage = "https://github.com/tumf/jev-cli"
|
|
21
|
+
Repository = "https://github.com/tumf/jev-cli"
|
|
22
|
+
Issues = "https://github.com/tumf/jev-cli/issues"
|
|
23
|
+
|
|
24
|
+
[project.scripts]
|
|
25
|
+
jev = "jev_cli:main"
|
|
26
|
+
|
|
27
|
+
[build-system]
|
|
28
|
+
requires = ["uv_build>=0.8.15,<0.9.0"]
|
|
29
|
+
build-backend = "uv_build"
|
|
30
|
+
|
|
31
|
+
[tool.uv.build-backend]
|
|
32
|
+
source-include = ["tests/**", "skills/**", "scripts/embed_skills.py"]
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""Copy canonical repository skills into the Python package."""
|
|
3
|
+
|
|
4
|
+
from pathlib import Path
|
|
5
|
+
import shutil
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
ROOT = Path(__file__).resolve().parents[1]
|
|
9
|
+
SOURCE = ROOT / "skills"
|
|
10
|
+
DESTINATION = ROOT / "src" / "jev_cli" / "bundled_skills"
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def main() -> None:
|
|
14
|
+
shutil.rmtree(DESTINATION, ignore_errors=True)
|
|
15
|
+
DESTINATION.mkdir(parents=True)
|
|
16
|
+
for skill in sorted(SOURCE.iterdir()):
|
|
17
|
+
if skill.is_dir() and (skill / "SKILL.md").is_file():
|
|
18
|
+
shutil.copytree(skill, DESTINATION / skill.name)
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
if __name__ == "__main__":
|
|
22
|
+
main()
|