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 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)
@@ -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()