jevctl 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (133) hide show
  1. package/CHANGELOG.md +44 -1
  2. package/NOTICE +4 -0
  3. package/README.md +54 -388
  4. package/SECURITY.md +5 -3
  5. package/dist/cli.js +105 -16
  6. package/dist/cli.js.map +1 -1
  7. package/dist/commands/ask.d.ts +5 -1
  8. package/dist/commands/ask.js +27 -10
  9. package/dist/commands/ask.js.map +1 -1
  10. package/dist/commands/auth.d.ts +14 -0
  11. package/dist/commands/auth.js +134 -0
  12. package/dist/commands/auth.js.map +1 -0
  13. package/dist/commands/batch.d.ts +28 -0
  14. package/dist/commands/batch.js +221 -0
  15. package/dist/commands/batch.js.map +1 -0
  16. package/dist/commands/classify.d.ts +34 -0
  17. package/dist/commands/classify.js +187 -0
  18. package/dist/commands/classify.js.map +1 -0
  19. package/dist/commands/compact.d.ts +29 -0
  20. package/dist/commands/compact.js +146 -0
  21. package/dist/commands/compact.js.map +1 -0
  22. package/dist/commands/config.d.ts +2 -1
  23. package/dist/commands/config.js +27 -10
  24. package/dist/commands/config.js.map +1 -1
  25. package/dist/commands/extract.d.ts +18 -0
  26. package/dist/commands/extract.js +108 -0
  27. package/dist/commands/extract.js.map +1 -0
  28. package/dist/commands/find.d.ts +5 -1
  29. package/dist/commands/find.js +30 -15
  30. package/dist/commands/find.js.map +1 -1
  31. package/dist/commands/match.d.ts +18 -0
  32. package/dist/commands/match.js +118 -0
  33. package/dist/commands/match.js.map +1 -0
  34. package/dist/commands/models.js +12 -10
  35. package/dist/commands/models.js.map +1 -1
  36. package/dist/commands/rerank.d.ts +15 -0
  37. package/dist/commands/rerank.js +82 -0
  38. package/dist/commands/rerank.js.map +1 -0
  39. package/dist/commands/route.d.ts +19 -0
  40. package/dist/commands/route.js +120 -0
  41. package/dist/commands/route.js.map +1 -0
  42. package/dist/commands/screen.d.ts +5 -1
  43. package/dist/commands/screen.js +27 -10
  44. package/dist/commands/screen.js.map +1 -1
  45. package/dist/commands/verify.d.ts +5 -1
  46. package/dist/commands/verify.js +23 -12
  47. package/dist/commands/verify.js.map +1 -1
  48. package/dist/config.d.ts +66 -6
  49. package/dist/config.js +53 -2
  50. package/dist/config.js.map +1 -1
  51. package/dist/context.d.ts +4 -0
  52. package/dist/context.js +11 -5
  53. package/dist/context.js.map +1 -1
  54. package/dist/core/ask.js +8 -3
  55. package/dist/core/ask.js.map +1 -1
  56. package/dist/core/batch.d.ts +42 -0
  57. package/dist/core/batch.js +93 -0
  58. package/dist/core/batch.js.map +1 -0
  59. package/dist/core/classify.d.ts +103 -0
  60. package/dist/core/classify.js +216 -0
  61. package/dist/core/classify.js.map +1 -0
  62. package/dist/core/compact.d.ts +32 -0
  63. package/dist/core/compact.js +47 -0
  64. package/dist/core/compact.js.map +1 -0
  65. package/dist/core/extract.d.ts +58 -0
  66. package/dist/core/extract.js +214 -0
  67. package/dist/core/extract.js.map +1 -0
  68. package/dist/core/find.js +3 -0
  69. package/dist/core/find.js.map +1 -1
  70. package/dist/core/match.d.ts +55 -0
  71. package/dist/core/match.js +114 -0
  72. package/dist/core/match.js.map +1 -0
  73. package/dist/core/rerank.d.ts +47 -0
  74. package/dist/core/rerank.js +60 -0
  75. package/dist/core/rerank.js.map +1 -0
  76. package/dist/core/route.d.ts +74 -0
  77. package/dist/core/route.js +153 -0
  78. package/dist/core/route.js.map +1 -0
  79. package/dist/core/transcript.d.ts +15 -0
  80. package/dist/core/transcript.js +118 -0
  81. package/dist/core/transcript.js.map +1 -0
  82. package/dist/credentials.d.ts +30 -0
  83. package/dist/credentials.js +161 -0
  84. package/dist/credentials.js.map +1 -0
  85. package/dist/errors.js.map +1 -1
  86. package/dist/index.d.ts +10 -0
  87. package/dist/index.js +10 -0
  88. package/dist/index.js.map +1 -1
  89. package/dist/input.js +1 -1
  90. package/dist/input.js.map +1 -1
  91. package/dist/lib.d.ts +2 -0
  92. package/dist/lib.js +9 -0
  93. package/dist/lib.js.map +1 -1
  94. package/dist/output.d.ts +41 -3
  95. package/dist/output.js +131 -6
  96. package/dist/output.js.map +1 -1
  97. package/dist/provider.d.ts +8 -0
  98. package/dist/provider.js +44 -4
  99. package/dist/provider.js.map +1 -1
  100. package/dist/vendor/compaction/compact.d.ts +29 -0
  101. package/dist/vendor/compaction/compact.js +236 -0
  102. package/dist/vendor/compaction/compact.js.map +1 -0
  103. package/dist/vendor/compaction/index.d.ts +4 -0
  104. package/dist/vendor/compaction/index.js +8 -0
  105. package/dist/vendor/compaction/index.js.map +1 -0
  106. package/dist/vendor/compaction/request.d.ts +19 -0
  107. package/dist/vendor/compaction/request.js +53 -0
  108. package/dist/vendor/compaction/request.js.map +1 -0
  109. package/dist/vendor/compaction/state.d.ts +28 -0
  110. package/dist/vendor/compaction/state.js +258 -0
  111. package/dist/vendor/compaction/state.js.map +1 -0
  112. package/dist/vendor/compaction/types.d.ts +177 -0
  113. package/dist/vendor/compaction/types.js +4 -0
  114. package/dist/vendor/compaction/types.js.map +1 -0
  115. package/docs/ask.md +52 -0
  116. package/docs/auth.md +53 -0
  117. package/docs/batch.md +48 -0
  118. package/docs/classify.md +55 -0
  119. package/docs/compact.md +58 -0
  120. package/docs/config.md +81 -0
  121. package/docs/extract.md +59 -0
  122. package/docs/find.md +49 -0
  123. package/docs/guidelines.md +19 -0
  124. package/docs/library.md +41 -0
  125. package/docs/match.md +52 -0
  126. package/docs/output.md +65 -0
  127. package/docs/recipes.md +78 -0
  128. package/docs/rerank.md +44 -0
  129. package/docs/route.md +57 -0
  130. package/docs/screen.md +53 -0
  131. package/docs/troubleshooting.md +17 -0
  132. package/docs/verify.md +58 -0
  133. package/package.json +9 -6
@@ -0,0 +1,19 @@
1
+ # Guidelines for good results
2
+
3
+ **Write claims as single, checkable statements.** "The API returns JSON and supports pagination" is two claims. Split them so each gets its own verdict.
4
+
5
+ **Give the model everything it needs, and only that.** Evidence should contain the passages the claims depend on. Very long, unrelated evidence dilutes accuracy and costs more. For quote-level checks, locate the passage in code first.
6
+
7
+ **Put domain rules in descriptions.** For `classify`, `route`, and `ask --choice`, the option descriptions are where your rules go, not the label names. Always include an escape option (`--other`, `none`) unless every input is known to fit.
8
+
9
+ **Treat thresholds as starting points.** The defaults (`0.8` auto-accept, `0.75` block, `0.25` review, `0.7`/`0.35` exists, `0.6` min confidence) come from TypeSafe's published cookbooks. Run `jev` over a sample of your own data with `--json`, look at the distributions, and set thresholds that match the cost of a wrong answer. Then pin a model version with `-m jev-1.13.0` so an alias update does not silently shift results.
10
+
11
+ **Read confidence correctly.** For `choice` and `score` answers, confidence measures how concentrated the distribution is. Low confidence means the options were close, not that the model is wrong; look at `probabilities` before deciding. `noul` answers carry no separate confidence; a value near `0.5` means "as likely yes as no".
12
+
13
+ **Keep policy in your code.** `jev` reports judgments. Whether to block, retry, escalate, or ignore is your decision, expressed through `--fail-on` or by reading the JSON.
14
+
15
+ **Mind what you send.** Everything you pass goes to the configured provider. Do not include secrets or data you are not permitted to share. `--dry-run` shows the exact payload.
16
+
17
+ **Batch.** Several questions in one `ask` call, or many rows through `batch`, cost less and finish sooner than separate calls. Only input tokens are billed; the usage footer shows them.
18
+
19
+ **Prefer direct TypeSafe.** Proxies add latency and lag behind on model versions.
@@ -0,0 +1,41 @@
1
+ # Use from Node.js
2
+
3
+ The same functions the CLI uses are exported from the `jevctl` package, so you can embed judgments in a script without shelling out.
4
+
5
+ ```ts
6
+ import { createAsk, runVerify, runScreen, runClassify, runCompact } from "jevctl";
7
+
8
+ const ask = createAsk({ provider: "auto", model: "jev-latest", timeoutMs: 30_000 });
9
+
10
+ const verdicts = await runVerify(ask, {
11
+ claims: ["The ordinance mentions reflective gear."],
12
+ evidence: [{ id: "ordinance", text: ordinanceText }],
13
+ autoAccept: 0.8,
14
+ });
15
+ console.log(verdicts.results[0].verdict, verdicts.results[0].confidence);
16
+
17
+ const screened = await runScreen(ask, { text: pageHtml, purpose: "extract prices", blockAt: 0.75, reviewAt: 0.25 });
18
+ if (screened.recommendation.action === "block") throw new Error(screened.recommendation.reason);
19
+
20
+ const label = await runClassify(ask, {
21
+ text: ticket,
22
+ labels: [{ label: "billing", description: null }, { label: "technical", description: null }],
23
+ other: true,
24
+ minConfidence: 0.6,
25
+ });
26
+ ```
27
+
28
+ Every `run*` function takes an `AskFn` first. `createAsk` builds one from the environment (or from stored credentials via `withStoredCredentials`); in tests, pass your own `async (state, questions) => ({ answers, usage, provider, model })`.
29
+
30
+ | Export | From |
31
+ | --- | --- |
32
+ | `runVerify`, `runScreen`, `runFind`, `runAsk`, `runClassify`, `runClassifyMulti`, `runClassifyTaxonomy`, `runExtract`, `runRerank`, `runMatch`, `runRoute`, `runCompact` | `core/*` |
33
+ | `build*Request` | The exact `state` and `questions` a command would send |
34
+ | `parseRows`, `runBatch` | Row parsing and the concurrency pool |
35
+ | `parseTranscript` | Claude Code session log or messages JSON to `Message[]` |
36
+ | `createAsk`, `resolveProvider`, `providerModel` | Providers |
37
+ | `resolveConfig`, `configPath` | Configuration |
38
+ | `resolveStore`, `withStoredCredentials` | Stored credentials |
39
+ | `compaction` | The vendored compaction library namespace |
40
+
41
+ Types are included. The package is ESM only.
package/docs/match.md ADDED
@@ -0,0 +1,52 @@
1
+ # jev match
2
+
3
+ Decide whether pairs of records describe the same thing: `same`, `different`, or `unclear`.
4
+
5
+ ```bash
6
+ jev match (--pairs <ref> | --left <ref> --right <ref> | --dedupe <ref>) [--kind <text>] [options]
7
+ ```
8
+
9
+ ## When to use
10
+
11
+ Dedupe a contact export, align your catalog with a supplier's, merge duplicate issues. One Score per pair has three levels that map to actions: leave unlinked, send to a person, merge. The decision is the most likely level, so there is no threshold to tune.
12
+
13
+ ## Options
14
+
15
+ | Option | Meaning |
16
+ | --- | --- |
17
+ | `-p, --pairs <ref>` | JSON: `[["a","b"], ...]` or `[{"left": ..., "right": ...}]`. Items are strings or `{id, text}`. |
18
+ | `--left <ref> --right <ref>` | Two JSON item lists; every left item is compared with every right item |
19
+ | `-d, --dedupe <ref>` | One JSON item list; every pair within it is compared |
20
+ | `-k, --kind <text>` | What the records are, e.g. `"customer contacts"`. Sharpens the question. |
21
+ | `--fail-on <list>` | Exit 2 when any pair is `same`, `unclear`, or `different` |
22
+
23
+ Limit: 200 pairs per call, sent in groups of 50. For large sets, block first (by postcode, name prefix, category) and match within blocks.
24
+
25
+ ## Output
26
+
27
+ `results[]` with `left`, `right` (ids), `left_text`, `right_text`, `decision`, `confidence`, `probabilities` (`different`, `unclear`, `same`); `summary` counts.
28
+
29
+ `unclear` is a real outcome meaning a person should look, not a weak `same`.
30
+
31
+ ## Example
32
+
33
+ ```bash
34
+ jev match --dedupe @contacts.json --kind "customer contacts"
35
+ ```
36
+
37
+ ```text
38
+ Decision Conf Left Right
39
+ --------- ---- ------ ------
40
+ same 0.91 c_1042 c_2210
41
+ unclear 0.48 c_1042 c_3187
42
+ different 0.97 c_2210 c_3187
43
+
44
+ 1 same · 1 unclear · 1 different
45
+ ```
46
+
47
+ ```bash
48
+ # Only the pairs a human should check
49
+ jev match --dedupe @contacts.json --json | jq -r '.results[] | select(.decision=="unclear") | "\(.left) ~ \(.right)"'
50
+ ```
51
+
52
+ Pattern: [entity alignment cookbook](https://docs.typesafe.ai/cookbooks/entity_alignment).
package/docs/output.md ADDED
@@ -0,0 +1,65 @@
1
+ # Output formats
2
+
3
+ Every command renders the same result in six formats. Pick one with `--format`, or the shortcuts `--json` and `--md`. Set a default with `JEV_FORMAT` or `jev config set format <name>`.
4
+
5
+ | Format | What you get | Use it for |
6
+ | --- | --- | --- |
7
+ | `text` (default) | A padded table or short lines, colored on a terminal | Reading at the prompt |
8
+ | `json` | The full result, pretty-printed | Scripts, `jq` |
9
+ | `jsonl` | The full result on one line | Log pipelines, appending to files |
10
+ | `md` | GitHub-flavored Markdown: a table, or a field/value table for single answers | PR comments, `$GITHUB_STEP_SUMMARY`, chat |
11
+ | `csv` | The table only, RFC 4180 quoting | Spreadsheets |
12
+ | `tsv` | The table only, tab separated | `cut`, `awk` |
13
+
14
+ `--json` and `--format json` are the same. `--md` and `--format md` are the same.
15
+
16
+ ## Rules that apply to all formats
17
+
18
+ - `-q` removes the token usage footer from `text` and `md`. Other formats never include it.
19
+ - `--no-color` or `NO_COLOR=1` removes color from `text`. Other formats never include it.
20
+ - Exit codes do not depend on the format. `jev screen ... --md` still exits 2 on `block`.
21
+ - `csv` and `tsv` need something tabular. Commands whose result is a single answer (`classify` single mode, `route`, `screen`, `ask`) emit `field,value` rows instead. `compact` with nothing to decide, and `auth login`, have no table; use `--json` or `--pluck` there.
22
+ - `--dry-run` always prints JSON.
23
+
24
+ ## --pluck: one value out
25
+
26
+ `--pluck <path>` prints a single value from the JSON result instead of the whole thing. Paths use dots, `[n]` for an index, and `[]` to map over an array (one line per element).
27
+
28
+ ```bash
29
+ jev classify @t.txt -l bug,feature --pluck label # bug
30
+ jev verify a b -e @spec.md --pluck results[].verdict # one verdict per line
31
+ jev extract @inv.txt --want amount --pluck fields.amount.normalized.value
32
+ jev route "$msg" -H refund,cancel --pluck handler --fail-on unrouted && echo routed
33
+ ```
34
+
35
+ Scalars print raw, arrays print one element per line, objects print as compact JSON. Combine with `--json` to get the plucked value as pretty JSON. Exit codes are unchanged, so `--pluck` works inside `$(...)` and `if`. A path that matches nothing is an error (exit 1) so a typo cannot read as an empty value; `batch` rows are the exception and print an empty line.
36
+
37
+ ## batch
38
+
39
+ `jev batch` streams one JSON record per row by default (that is its `text` and `jsonl` behavior).
40
+
41
+ | Flag | Effect |
42
+ | --- | --- |
43
+ | `--format json` | Collect all records into one JSON array at the end |
44
+ | `--format md`, `csv`, `tsv` | A summary table with `id`, `ok`, `failed`, and a one-cell `result` (label, handler, action, verdicts, extracted values, ...) |
45
+ | `--pluck <path>` | One value per row, e.g. `--pluck result.label` |
46
+
47
+ ## Examples
48
+
49
+ Post a verification report into a GitHub Actions job summary:
50
+
51
+ ```bash
52
+ jev verify --claims @claims.txt -e @spec.md --md --fail-on none >> "$GITHUB_STEP_SUMMARY"
53
+ ```
54
+
55
+ Feed match decisions into a spreadsheet:
56
+
57
+ ```bash
58
+ jev match --dedupe @contacts.json --format csv > pairs.csv
59
+ ```
60
+
61
+ Use a single field in a shell condition:
62
+
63
+ ```bash
64
+ if [ "$(jev screen @page.html --pluck recommendation.action)" = "pass" ]; then …; fi
65
+ ```
@@ -0,0 +1,78 @@
1
+ # Recipes
2
+
3
+ Copy, adjust thresholds, ship.
4
+
5
+ ## Gate a pull request on its own description
6
+
7
+ One claim per line in `claims.txt`, checked against the diff:
8
+
9
+ ```bash
10
+ git diff origin/main...HEAD | jev verify --claims @claims.txt --evidence - --fail-on contradicted,unsupported
11
+ ```
12
+
13
+ ## Guard an agent's web fetches
14
+
15
+ ```bash
16
+ page=$(curl -s "$url")
17
+ if printf '%s' "$page" | jev screen --purpose "$task" --fail-on block,review,skip -q; then
18
+ printf '%s' "$page" | my-agent --context -
19
+ fi
20
+ ```
21
+
22
+ ## Route a support ticket in a shell script
23
+
24
+ ```bash
25
+ team=$(jev classify @ticket.txt -l billing,technical,sales --other --json | jq -r .label)
26
+ ```
27
+
28
+ ## Label a whole backlog, flag the uncertain ones
29
+
30
+ ```bash
31
+ jev batch classify -i @issues.jsonl -o labeled.jsonl -- -l bug,feature,question,docs --other --fail-on review
32
+ jq -r 'select(.failed) | .id' labeled.jsonl
33
+ ```
34
+
35
+ ## Pull fields from every email in a folder
36
+
37
+ ```bash
38
+ for f in inbox/*.eml; do jq -n --arg id "$f" --arg text "$(cat "$f")" '{id:$id,text:$text}'; done \
39
+ | jev batch extract -i - -- --want sender=email:the sender --want reply_by=date:the reply deadline --want amount
40
+ ```
41
+
42
+ ## Rerank search results before answering from them
43
+
44
+ ```bash
45
+ my-search "$q" --json | jev rerank "$q" -c - --min 0.6 --json | jq '.kept'
46
+ ```
47
+
48
+ ## Dedupe a contact export, review only the unclear pairs
49
+
50
+ ```bash
51
+ jev match --dedupe @contacts.json --kind "customer contacts" --json \
52
+ | jq -r '.results[] | select(.decision=="unclear") | "\(.left) ~ \(.right)"' > needs-review.txt
53
+ ```
54
+
55
+ ## Route chat messages to typed handlers in a bot
56
+
57
+ ```bash
58
+ jev route "$message" --handlers-json @handlers.json --fail-on unrouted --json | jq '{handler, args}'
59
+ ```
60
+
61
+ ## Find the right file, then open it
62
+
63
+ ```bash
64
+ jev find "where is retry logic configured" --files src/**/*.ts --json | jq -r '.top[0].id' | xargs code
65
+ ```
66
+
67
+ ## Check that a knowledge base actually answers a question
68
+
69
+ ```bash
70
+ jev find "$question" --lines @faq.txt --fail-on absent,partial --json
71
+ ```
72
+
73
+ ## Compact a Claude Code session offline and inspect what would go
74
+
75
+ ```bash
76
+ jev compact @~/.claude/projects/-Users-me-repo/$SESSION.jsonl --json \
77
+ | jq '.decisions[] | select(.action != "keep") | {id, tool, action}'
78
+ ```
package/docs/rerank.md ADDED
@@ -0,0 +1,44 @@
1
+ # jev rerank
2
+
3
+ Score every candidate's relevance to a query independently, then sort. Several can be relevant, or none.
4
+
5
+ ```bash
6
+ jev rerank <query> (--files <paths...> | --candidates <ref> | --lines <ref>) [options]
7
+ ```
8
+
9
+ ## When to use
10
+
11
+ In front of any search: take the top 30 from BM25 or a vector index, keep what Jev says is relevant. The cookbook shows top-1 accuracy rising from 5% to 18% with one judgment per pair. Where [`find`](find.md) asks "which one is best", `rerank` asks "is this one relevant" for each.
12
+
13
+ ## Options
14
+
15
+ | Option | Meaning | Default |
16
+ | --- | --- | --- |
17
+ | `<query>` | What results should be relevant to | required |
18
+ | `-f/-c/-l` | Candidates, same forms as `find` | |
19
+ | `-k, --top-k <n>` | How many ranked results to return | `10` |
20
+ | `--min <p>` | Relevance at or above which a candidate is `kept` | `0.5` |
21
+ | `--criteria <text>` | What counts as relevant, e.g. `"a passage stating the rule, not commentary"` | |
22
+ | `--fail-on <list>` | Exit 2 on `empty` (nothing kept) | `none` |
23
+
24
+ ## Output
25
+
26
+ `ranked[]` with `id`, `relevance`, `kept`, `text`; `kept[]` ids. Up to 250 candidates per call.
27
+
28
+ ## Example
29
+
30
+ ```bash
31
+ my-search "$q" --json | jev rerank "$q" -c - --min 0.6 --json | jq '.kept'
32
+ ```
33
+
34
+ ```text
35
+ 2 of 5 shown are relevant (min 0.6) statute of limitations for contract claims
36
+
37
+ # Rel Id Text
38
+ - ---- ---- ---- ------------------------------------------------------------
39
+ 1 0.94 keep p17 An action for breach of a written contract must be brought…
40
+ 2 0.71 keep p03 The limitations period begins when the breach occurs…
41
+ 3 0.22 drop p09 Courts have discussed equitable tolling in other contexts…
42
+ ```
43
+
44
+ Pattern: [reranking cookbook](https://docs.typesafe.ai/cookbooks/rerank_typesafe).
package/docs/route.md ADDED
@@ -0,0 +1,57 @@
1
+ # jev route
2
+
3
+ Pick a handler for a request and fill that handler's arguments from closed sets, in one call.
4
+
5
+ ```bash
6
+ jev route [request] (--handlers <list> | --handlers-json <ref>) [options]
7
+ ```
8
+
9
+ ## When to use
10
+
11
+ Turn free text into a typed call: a chat message into a bot command, a support request into a queue plus fields, a voice transcript into an action. Argument questions for every handler are asked in the same request; only the chosen handler's answers come back. A `none` handler is always available so the model can decline.
12
+
13
+ ## Options
14
+
15
+ | Option | Meaning | Default |
16
+ | --- | --- | --- |
17
+ | `[request]` | Text, `@file`, or `-` | stdin |
18
+ | `-H, --handlers <list>` | Handlers without arguments: `refund:money back,cancel:stop an order,support` | |
19
+ | `--handlers-json <ref>` | Handlers with arguments, see below | |
20
+ | `-i, --instructions <text>` | Replace the default routing question | |
21
+ | `--min-confidence <p>` | Below this confidence the route is `review` | `0.6` |
22
+ | `--state-json` | Parse the request as JSON | |
23
+ | `--fail-on <list>` | Exit 2 on `review` or `unrouted` (no handler fits) | `none` |
24
+
25
+ ## Handlers JSON
26
+
27
+ Each value is a description string, `null`, or `{"description", "args"}`. Each arg is one of:
28
+
29
+ ```json
30
+ {"type": "choice", "options": ["full", "partial"]}
31
+ {"type": "choice", "options": {"full": "entire order", "partial": "some items"}, "instructions": "optional"}
32
+ {"type": "noul", "instructions": "Does the customer need this immediately?"}
33
+ {"type": "score", "levels": ["calm", "annoyed", "furious"]}
34
+ ```
35
+
36
+ ## Output
37
+
38
+ `handler` (or `null`), `confidence`, `action` (`auto`, `review`, `none`), `probabilities` over handlers, and `args` with a typed `value` per argument (`null` when the request does not say).
39
+
40
+ ## Example
41
+
42
+ ```bash
43
+ jev route "cancel order 4411 and refund the whole thing, today please" --handlers-json @handlers.json
44
+ ```
45
+
46
+ ```text
47
+ refund conf 0.87 auto
48
+ [refund 0.90, cancel 0.08, support 0.01, none 0.01]
49
+ scope = full conf 0.93
50
+ urgent = yes p 0.88
51
+ ```
52
+
53
+ ```bash
54
+ jev route "$message" --handlers-json @handlers.json --fail-on unrouted --json | jq '{handler, args}'
55
+ ```
56
+
57
+ Patterns: [function calling](https://docs.typesafe.ai/cookbooks/function_calling), [intent routing](https://docs.typesafe.ai/patterns/intent-routing).
package/docs/screen.md ADDED
@@ -0,0 +1,53 @@
1
+ # jev screen
2
+
3
+ Judge text before an AI agent reads it: is it trying to hijack the agent, does it have substance, is it relevant to the task.
4
+
5
+ ```bash
6
+ jev screen [text] [--purpose <text>] [options]
7
+ ```
8
+
9
+ ## When to use
10
+
11
+ On every untrusted input an agent consumes: fetched web pages, emails, tickets, uploaded documents, third-party tool output. It costs less than reading the page.
12
+
13
+ ## Options
14
+
15
+ | Option | Meaning | Default |
16
+ | --- | --- | --- |
17
+ | `[text]` | Text, `@file`, or `-`. Reads stdin when omitted and piped. | stdin |
18
+ | `-p, --purpose <text>` | What the consumer is trying to do. Enables the relevance check and the `skip` action. | |
19
+ | `--block-at <p>` | Injection probability that triggers `block` | `0.75` |
20
+ | `--review-at <p>` | Injection probability that triggers `review` | `0.25` |
21
+ | `--fail-on <list>` | Exit 2 when the recommendation is `block`, `review`, or `skip`. `none` to always exit 0. | `block` |
22
+
23
+ ## Output
24
+
25
+ | Field | Meaning |
26
+ | --- | --- |
27
+ | `probabilities.injection` | The text contains instructions aimed at an AI agent |
28
+ | `probabilities.substance` | The text has real content, not an error page or boilerplate |
29
+ | `probabilities.relevance` | The text is useful for `--purpose` (null without a purpose) |
30
+ | `recommendation.action` | `pass`, `review`, `block`, or `skip` |
31
+ | `recommendation.reason` | Which threshold fired |
32
+
33
+ `block` and `review` come from the injection probability; `skip` from low substance or relevance. The recommendation is advisory: `jev` never blocks anything itself.
34
+
35
+ ## Example
36
+
37
+ ```bash
38
+ curl -s https://shop.example/sale | jev screen --purpose "summarize the products"
39
+ ```
40
+
41
+ ```text
42
+ BLOCK injection probability 0.99 >= block threshold 0.75
43
+ injection 0.99 · substance 0.97 · relevance 0.97
44
+ ```
45
+
46
+ ```bash
47
+ # Only feed the page to the agent if it is safe and relevant
48
+ if printf '%s' "$page" | jev screen --purpose "$task" --fail-on block,review,skip -q; then
49
+ printf '%s' "$page" | my-agent --context -
50
+ fi
51
+ ```
52
+
53
+ Pattern: [guardrails cookbook](https://docs.typesafe.ai/cookbooks/llm_guardrails).
@@ -0,0 +1,17 @@
1
+ # Troubleshooting
2
+
3
+ | Symptom | Fix |
4
+ | --- | --- |
5
+ | `No credentials found` | Run `jev auth login`, or export `TYPESAFE_API_KEY`. `jev auth status` shows what was found. |
6
+ | `HTTP 401` | The key is wrong or revoked. Check it at console.typesafe.ai and log in again. |
7
+ | `HTTP 429` | Rate limited. The TypeSafe provider retries automatically; if it persists, slow down or batch questions. |
8
+ | `Malformed response from <model>` | The API (or a proxy in front of it) returned something other than an answer per question. Retry; check `TYPESAFE_BASE_URL` if set. `jev` never treats a missing answer as probability 0. |
9
+ | `Request timed out` | Raise `--timeout` or set `JEV_TIMEOUT_MS`. Large evidence takes longer. |
10
+ | `Expected ... on stdin but stdin is a terminal` | You used `-` without piping anything. Pass text or `@file`. |
11
+ | `Too many candidates` / `exceeds the limit` | `find` and `rerank` take 250 candidates, `match` 200 pairs. Pre-filter or block, then split. |
12
+ | `history too large for Jev` (`compact`) | Lower `--preserve-recent` or raise `--max-state-tokens` slightly (hard limit is 32k for state plus the longest question). |
13
+ | `Invalid <command> flags` (`batch`) | Sub-command flags go after `--`; do not pass the text argument, rows supply it. |
14
+ | Colors in captured output | `--no-color` or `NO_COLOR=1` |
15
+ | Want to see the request | `--dry-run` |
16
+ | Want a stack trace | `JEV_DEBUG=1` |
17
+ | Keychain prompts on every call (macOS) | Click "Always Allow" once, or use `JEV_CREDENTIAL_STORE=file` |
package/docs/verify.md ADDED
@@ -0,0 +1,58 @@
1
+ # jev verify
2
+
3
+ Check claims against evidence. Each claim gets a verdict, the full probability distribution, a confidence, and whether it can stand automatically or needs a person.
4
+
5
+ ```bash
6
+ jev verify [claims...] --evidence <ref> [--evidence <ref>...] [options]
7
+ ```
8
+
9
+ ## When to use
10
+
11
+ Fact-check a PR description against its diff, a report against its sources, or an AI summary against the document it summarizes. For quote-level citation checks, locate the passage in code first and send only that.
12
+
13
+ ## Options
14
+
15
+ | Option | Meaning | Default |
16
+ | --- | --- | --- |
17
+ | `[claims...]` | Claims as arguments | |
18
+ | `-c, --claims <ref>` | Claims from a file or stdin: one per line, or a JSON array of strings | |
19
+ | `-e, --evidence <ref>` | Evidence text, `@file`, or `-`. Repeat for several sources; files are labeled by filename. | required |
20
+ | `--evidence-json <ref>` | Evidence as JSON: `["text"]`, `[{"id","text"}]`, or `{"id": "text"}` | |
21
+ | `--auto-accept <p>` | Confidence at or above which a verdict is `auto` rather than `review` | `0.8` |
22
+ | `--fail-on <list>` | Exit 2 if any result is `contradicted`, `unsupported`, `review`, or `unknown`. `none` to always exit 0. | `contradicted` |
23
+
24
+ ## Output
25
+
26
+ | Field | Meaning |
27
+ | --- | --- |
28
+ | `results[].verdict` | `verified`, `contradicted`, `unsupported` (evidence is silent), or `unknown` |
29
+ | `results[].confidence` | 0 to 1, how concentrated the distribution is |
30
+ | `results[].action` | `auto` or `review` |
31
+ | `results[].probabilities` | `supports`, `contradicts`, `says_nothing` |
32
+ | `results[].supporting_evidence` | The evidence id the claim rests on, when more than one source was given |
33
+ | `summary` | Counts of each verdict and of `review` |
34
+
35
+ ## Example
36
+
37
+ ```bash
38
+ jev verify --claims @claims.txt -e @spec.md -e @rfc.txt --fail-on contradicted,unsupported
39
+ git diff main | jev verify "This change only touches tests" --evidence -
40
+ ```
41
+
42
+ ```text
43
+ # Verdict Conf Action Claim Source
44
+ - ------------ ---- ------ -------------------------------- -------
45
+ 1 contradicted 1.00 auto Helmets are optional for adults spec.md
46
+ 2 verified 0.96 auto Reflective gear is mentioned rfc.txt
47
+ 3 unsupported 0.71 review The fine is 50 dollars -
48
+
49
+ 1 verified · 1 contradicted · 1 unsupported · 1 need review (auto-accept ≥ 0.8)
50
+ ```
51
+
52
+ ## Tips
53
+
54
+ - One checkable statement per claim. Split compound sentences.
55
+ - `unsupported` often means the wrong source was supplied, not that the claim is false.
56
+ - Batch many claims against the same evidence with `jev batch verify -i @claims.txt -- -e @spec.md`.
57
+
58
+ Pattern: [citation check cookbook](https://docs.typesafe.ai/cookbooks/citation_check).
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "jevctl",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "description": "Command-line tool for TypeSafe's Jev AI model. Check claims against evidence, detect prompt injection, find the best match in a list, or ask your own yes/no, multiple-choice, and rating questions. Returns probabilities, not text.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -9,7 +9,7 @@
9
9
  "type": "git",
10
10
  "url": "git+https://github.com/Nasrallah-AL/jev-cli.git"
11
11
  },
12
- "homepage": "https://github.com/Nasrallah-AL/jev-cli#readme",
12
+ "homepage": "https://jevcli.vectorz.app/",
13
13
  "bugs": "https://github.com/Nasrallah-AL/jev-cli/issues",
14
14
  "bin": {
15
15
  "jev": "dist/cli.js"
@@ -24,6 +24,7 @@
24
24
  },
25
25
  "files": [
26
26
  "dist",
27
+ "docs",
27
28
  "README.md",
28
29
  "LICENSE",
29
30
  "NOTICE",
@@ -44,8 +45,10 @@
44
45
  "test:watch": "vitest",
45
46
  "test:coverage": "vitest run --coverage",
46
47
  "test:e2e": "JEV_E2E=1 vitest run test/e2e.test.ts",
47
- "check": "npm run typecheck && npm run lint && npm test",
48
- "prepublishOnly": "npm run clean && npm run check && npm run build"
48
+ "check": "npm run typecheck && npm run typecheck:hooks && node scripts/sync-hooks.mjs --check && npm run lint && npm test",
49
+ "prepublishOnly": "npm run clean && npm run check && npm run build",
50
+ "sync:hooks": "node scripts/sync-hooks.mjs",
51
+ "typecheck:hooks": "tsc -p plugin/tsconfig.hooks.json"
49
52
  },
50
53
  "keywords": [
51
54
  "cli",
@@ -66,10 +69,10 @@
66
69
  },
67
70
  "devDependencies": {
68
71
  "@biomejs/biome": "^2.5.14",
69
- "@types/node": "^22.0.0",
72
+ "@types/node": "^26.5.1",
70
73
  "@vitest/coverage-v8": "^5.0.1",
71
74
  "tsx": "^4.23.13",
72
- "typescript": "^5.9.0",
75
+ "typescript": "^7.0.2",
73
76
  "vitest": "^5.0.1"
74
77
  },
75
78
  "publishConfig": {