jevctl 0.1.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 (63) hide show
  1. package/CHANGELOG.md +28 -0
  2. package/LICENSE +21 -0
  3. package/NOTICE +5 -0
  4. package/README.md +430 -0
  5. package/SECURITY.md +21 -0
  6. package/dist/cli.d.ts +4 -0
  7. package/dist/cli.js +78 -0
  8. package/dist/cli.js.map +1 -0
  9. package/dist/commands/ask.d.ts +15 -0
  10. package/dist/commands/ask.js +96 -0
  11. package/dist/commands/ask.js.map +1 -0
  12. package/dist/commands/config.d.ts +13 -0
  13. package/dist/commands/config.js +125 -0
  14. package/dist/commands/config.js.map +1 -0
  15. package/dist/commands/find.d.ts +16 -0
  16. package/dist/commands/find.js +97 -0
  17. package/dist/commands/find.js.map +1 -0
  18. package/dist/commands/models.d.ts +4 -0
  19. package/dist/commands/models.js +35 -0
  20. package/dist/commands/models.js.map +1 -0
  21. package/dist/commands/screen.d.ts +13 -0
  22. package/dist/commands/screen.js +64 -0
  23. package/dist/commands/screen.js.map +1 -0
  24. package/dist/commands/verify.d.ts +18 -0
  25. package/dist/commands/verify.js +97 -0
  26. package/dist/commands/verify.js.map +1 -0
  27. package/dist/config.d.ts +81 -0
  28. package/dist/config.js +147 -0
  29. package/dist/config.js.map +1 -0
  30. package/dist/context.d.ts +29 -0
  31. package/dist/context.js +54 -0
  32. package/dist/context.js.map +1 -0
  33. package/dist/core/ask.d.ts +59 -0
  34. package/dist/core/ask.js +103 -0
  35. package/dist/core/ask.js.map +1 -0
  36. package/dist/core/find.d.ts +48 -0
  37. package/dist/core/find.js +50 -0
  38. package/dist/core/find.js.map +1 -0
  39. package/dist/core/screen.d.ts +38 -0
  40. package/dist/core/screen.js +55 -0
  41. package/dist/core/screen.js.map +1 -0
  42. package/dist/core/verify.d.ts +55 -0
  43. package/dist/core/verify.js +74 -0
  44. package/dist/core/verify.js.map +1 -0
  45. package/dist/errors.d.ts +16 -0
  46. package/dist/errors.js +29 -0
  47. package/dist/errors.js.map +1 -0
  48. package/dist/index.d.ts +8 -0
  49. package/dist/index.js +12 -0
  50. package/dist/index.js.map +1 -0
  51. package/dist/input.d.ts +34 -0
  52. package/dist/input.js +116 -0
  53. package/dist/input.js.map +1 -0
  54. package/dist/lib.d.ts +63 -0
  55. package/dist/lib.js +123 -0
  56. package/dist/lib.js.map +1 -0
  57. package/dist/output.d.ts +26 -0
  58. package/dist/output.js +59 -0
  59. package/dist/output.js.map +1 -0
  60. package/dist/provider.d.ts +30 -0
  61. package/dist/provider.js +157 -0
  62. package/dist/provider.js.map +1 -0
  63. package/package.json +78 -0
package/dist/lib.js ADDED
@@ -0,0 +1,123 @@
1
+ // Pure helpers with no I/O. Question design follows the TypeSafe cookbooks
2
+ // (citation_check, llm_guardrails, semantic_find).
3
+ /** Max candidates in one `find` call. TypeSafe Choice supports up to 255 options. */
4
+ export const MAX_CANDIDATES = 250;
5
+ /** Per-candidate text cap (characters) to keep request size bounded. */
6
+ export const MAX_CANDIDATE_CHARS = 2000;
7
+ /** Sanitize a caller-supplied id into a safe Choice option key. */
8
+ export function sanitizeId(id) {
9
+ const cleaned = id.replace(/[^A-Za-z0-9_.-]+/g, "_").replace(/^_+|_+$/g, "");
10
+ return cleaned.length > 0 ? cleaned.slice(0, 64) : "";
11
+ }
12
+ /**
13
+ * Ensure ids exist, are safe, and are unique. `id` is the sanitized key sent to
14
+ * the model; `originalId` is what the caller passed (or the generated id).
15
+ */
16
+ export function ensureUniqueIds(items, fallbackPrefix) {
17
+ const used = new Set();
18
+ return items.map((item, i) => {
19
+ const raw = item.id ?? "";
20
+ const base = sanitizeId(raw) || `${fallbackPrefix}${i}`;
21
+ let id = base;
22
+ let n = 1;
23
+ while (used.has(id))
24
+ id = `${base}_${n++}`;
25
+ used.add(id);
26
+ return { ...item, id, originalId: raw || id };
27
+ });
28
+ }
29
+ /** Reverse lookup from sanitized id to the caller's original id. */
30
+ export function originalIds(items) {
31
+ return new Map(items.map((i) => [i.id, i.originalId]));
32
+ }
33
+ /** Truncate long text with an explicit marker so the model knows it is partial. */
34
+ export function truncate(text, maxChars) {
35
+ if (text.length <= maxChars)
36
+ return text;
37
+ return `${text.slice(0, maxChars)} […truncated]`;
38
+ }
39
+ /** Map a verify relation answer to a verdict label (citation-check cookbook). */
40
+ export const RELATION_TO_VERDICT = {
41
+ supports: "verified",
42
+ contradicts: "contradicted",
43
+ says_nothing: "unsupported",
44
+ };
45
+ /** Does this verdict stand on its own, or should a human confirm it? */
46
+ export function verifyAction(confidence, autoAccept) {
47
+ if (confidence === null)
48
+ return "review";
49
+ return confidence >= autoAccept ? "auto" : "review";
50
+ }
51
+ /**
52
+ * Screen recommendation from probabilities.
53
+ * injection: probability the text contains instructions aimed at an AI agent.
54
+ * substance: probability the text has substantive readable content (optional).
55
+ * relevance: probability the text is useful for the stated purpose (optional).
56
+ */
57
+ export function screenRecommendation(input) {
58
+ const { injection, relevance, substance, blockAt, reviewAt } = input;
59
+ const skipBelow = input.skipBelow ?? 0.3;
60
+ if (injection >= blockAt) {
61
+ return {
62
+ action: "block",
63
+ reason: `injection probability ${injection.toFixed(2)} >= block threshold ${blockAt}`,
64
+ };
65
+ }
66
+ if (injection >= reviewAt) {
67
+ return {
68
+ action: "review",
69
+ reason: `injection probability ${injection.toFixed(2)} >= review threshold ${reviewAt}`,
70
+ };
71
+ }
72
+ if (substance !== undefined && substance < skipBelow) {
73
+ return { action: "skip", reason: `little substantive content (substance ${substance.toFixed(2)})` };
74
+ }
75
+ if (relevance !== undefined && relevance < skipBelow) {
76
+ return {
77
+ action: "skip",
78
+ reason: `not relevant to the stated purpose (relevance ${relevance.toFixed(2)})`,
79
+ };
80
+ }
81
+ return { action: "pass", reason: "no signals above thresholds" };
82
+ }
83
+ /** Turn the exists Noul into a document-level verdict (semantic-find cookbook thresholds). */
84
+ export function existsVerdict(exists, found = 0.7, absent = 0.35) {
85
+ if (exists >= found)
86
+ return "answered";
87
+ return exists < absent ? "absent" : "partial";
88
+ }
89
+ /** Rank candidate ids by Choice probability, descending. Ties keep caller order. */
90
+ export function rankCandidates(candidates, probabilities) {
91
+ return candidates
92
+ .map((candidate, index) => ({
93
+ candidate: { ...candidate, probability: probabilities[candidate.id] ?? 0 },
94
+ index,
95
+ }))
96
+ .sort((a, b) => b.candidate.probability - a.candidate.probability || a.index - b.index)
97
+ .map(({ candidate }) => candidate);
98
+ }
99
+ /** Parse a comma-separated `--fail-on` list against the allowed values. */
100
+ export function parseFailOn(raw, allowed, fallback) {
101
+ if (raw === undefined)
102
+ return fallback;
103
+ const trimmed = raw.trim();
104
+ if (trimmed === "" || trimmed === "none")
105
+ return [];
106
+ const values = trimmed.split(",").map((v) => v.trim());
107
+ for (const v of values) {
108
+ if (!allowed.includes(v)) {
109
+ throw new Error(`Invalid --fail-on value "${v}". Allowed: ${allowed.join(", ")}, none.`);
110
+ }
111
+ }
112
+ return values;
113
+ }
114
+ /** Parse a probability-like flag (0..1). */
115
+ export function parseProbability(name, raw, fallback) {
116
+ if (raw === undefined)
117
+ return fallback;
118
+ const n = typeof raw === "number" ? raw : Number(raw);
119
+ if (!Number.isFinite(n) || n < 0 || n > 1)
120
+ throw new Error(`${name} must be a number between 0 and 1.`);
121
+ return n;
122
+ }
123
+ //# sourceMappingURL=lib.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lib.js","sourceRoot":"","sources":["../src/lib.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ import { styleText } from "node:util";
2
+ export type Format = "text" | "json";
3
+ export interface OutputOptions {
4
+ format: Format;
5
+ color: boolean;
6
+ quiet: boolean;
7
+ stream?: NodeJS.WritableStream;
8
+ }
9
+ /** Decide whether to colorize, honoring NO_COLOR, FORCE_COLOR, and TTY. */
10
+ export declare function shouldColor(env?: NodeJS.ProcessEnv, isTTY?: boolean): boolean;
11
+ type Style = Parameters<typeof styleText>[0];
12
+ export declare function paint(enabled: boolean, style: Style, text: string): string;
13
+ export declare function formatProbability(p: number | null | undefined): string;
14
+ /** Render rows as a padded table. First row is the header. */
15
+ export declare function table(rows: string[][], opts?: {
16
+ color?: boolean;
17
+ }): string;
18
+ /** Clip a string for table display. */
19
+ export declare function clip(text: string, max?: number): string;
20
+ export declare function usageLine(usage: {
21
+ input_tokens: number;
22
+ output_tokens: number;
23
+ }, model: string, provider: string): string;
24
+ /** Write a result either as JSON or via the provided text renderer. */
25
+ export declare function emit(opts: OutputOptions, payload: unknown, renderText: () => string): void;
26
+ export {};
package/dist/output.js ADDED
@@ -0,0 +1,59 @@
1
+ import { stripVTControlCharacters, styleText } from "node:util";
2
+ /** Decide whether to colorize, honoring NO_COLOR, FORCE_COLOR, and TTY. */
3
+ export function shouldColor(env = process.env, isTTY = process.stdout.isTTY) {
4
+ if (env.NO_COLOR !== undefined && env.NO_COLOR !== "")
5
+ return false;
6
+ if (env.FORCE_COLOR !== undefined && env.FORCE_COLOR !== "0")
7
+ return true;
8
+ return Boolean(isTTY);
9
+ }
10
+ export function paint(enabled, style, text) {
11
+ return enabled ? styleText(style, text) : text;
12
+ }
13
+ export function formatProbability(p) {
14
+ if (p === null || p === undefined || Number.isNaN(p))
15
+ return "-";
16
+ return p.toFixed(2);
17
+ }
18
+ /** Render rows as a padded table. First row is the header. */
19
+ export function table(rows, opts = {}) {
20
+ if (rows.length === 0)
21
+ return "";
22
+ const widths = [];
23
+ for (const row of rows) {
24
+ row.forEach((cell, i) => {
25
+ widths[i] = Math.max(widths[i] ?? 0, visibleLength(cell));
26
+ });
27
+ }
28
+ const render = (row) => row
29
+ .map((cell, i) => cell + " ".repeat((widths[i] ?? 0) - visibleLength(cell)))
30
+ .join(" ")
31
+ .trimEnd();
32
+ const [header, ...body] = rows;
33
+ const lines = [paint(opts.color ?? false, "bold", render(header))];
34
+ lines.push(widths.map((w) => "-".repeat(w)).join(" "));
35
+ for (const row of body)
36
+ lines.push(render(row));
37
+ return lines.join("\n");
38
+ }
39
+ function visibleLength(s) {
40
+ return stripVTControlCharacters(s).length;
41
+ }
42
+ /** Clip a string for table display. */
43
+ export function clip(text, max = 60) {
44
+ const oneLine = text.replace(/\s+/g, " ").trim();
45
+ return oneLine.length <= max ? oneLine : `${oneLine.slice(0, max - 1)}…`;
46
+ }
47
+ export function usageLine(usage, model, provider) {
48
+ return `${usage.input_tokens} in / ${usage.output_tokens} out tokens · ${model} via ${provider}`;
49
+ }
50
+ /** Write a result either as JSON or via the provided text renderer. */
51
+ export function emit(opts, payload, renderText) {
52
+ const stream = opts.stream ?? process.stdout;
53
+ if (opts.format === "json") {
54
+ stream.write(`${JSON.stringify(payload, null, 2)}\n`);
55
+ return;
56
+ }
57
+ stream.write(`${renderText()}\n`);
58
+ }
59
+ //# sourceMappingURL=output.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"output.js","sourceRoot":"","sources":["../src/output.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,30 @@
1
+ import type { ProviderName } from "./config.js";
2
+ export type ResolvedProvider = Exclude<ProviderName, "auto">;
3
+ export interface Usage {
4
+ input_tokens: number;
5
+ output_tokens: number;
6
+ }
7
+ export interface AskResult {
8
+ answers: Record<string, any>;
9
+ usage: Usage;
10
+ provider: ResolvedProvider;
11
+ model: string;
12
+ }
13
+ /** The single dependency every command needs: ask Jev questions about state. */
14
+ export type AskFn = (state: unknown, questions: Record<string, unknown>) => Promise<AskResult>;
15
+ export interface ProviderOptions {
16
+ provider: ProviderName;
17
+ model: string;
18
+ timeoutMs: number;
19
+ env?: NodeJS.ProcessEnv;
20
+ fetch?: typeof fetch;
21
+ signal?: AbortSignal;
22
+ }
23
+ /** OpenRouter has no `latest` alias; map it to the current pinned release. */
24
+ export declare const OPENROUTER_LATEST = "jev-1.13";
25
+ /** Decide which transport to use from explicit choice plus available credentials. */
26
+ export declare function resolveProvider(env: NodeJS.ProcessEnv, explicit?: ProviderName): ResolvedProvider;
27
+ /** Model slug as each proxy expects it. */
28
+ export declare function providerModel(provider: ResolvedProvider, model: string): string;
29
+ /** Build an `AskFn` bound to the resolved provider. */
30
+ export declare function createAsk(opts: ProviderOptions): AskFn;
@@ -0,0 +1,157 @@
1
+ // Jev transport: TypeSafe direct (default), OpenRouter Decisions, or Cloudflare
2
+ // Workers AI. All speak the {state, questions} -> answers contract; URL, auth,
3
+ // and model slugs differ. Proxies add hops, so direct TypeSafe is the
4
+ // recommended default.
5
+ import { TypeSafeClient } from "@typesafe-ai/sdk";
6
+ import { CliError } from "./errors.js";
7
+ const USER_AGENT = "jevctl";
8
+ const REFERER = "https://github.com/Nasrallah-AL/jev-cli";
9
+ /** OpenRouter has no `latest` alias; map it to the current pinned release. */
10
+ export const OPENROUTER_LATEST = "jev-1.13";
11
+ /** Decide which transport to use from explicit choice plus available credentials. */
12
+ export function resolveProvider(env, explicit = "auto") {
13
+ const hasTypesafe = Boolean(env.TYPESAFE_API_KEY?.trim());
14
+ const hasOpenRouter = /^sk-or-/.test(env.OPENROUTER_API_KEY ?? "");
15
+ const cfToken = env.JEV_CLOUDFLARE_API_TOKEN || env.CLOUDFLARE_API_TOKEN;
16
+ const hasCloudflare = Boolean(cfToken && env.CLOUDFLARE_ACCOUNT_ID);
17
+ switch (explicit) {
18
+ case "typesafe":
19
+ if (!hasTypesafe)
20
+ throw new CliError("Provider is typesafe but TYPESAFE_API_KEY is not set.");
21
+ return "typesafe";
22
+ case "openrouter":
23
+ if (!hasOpenRouter) {
24
+ throw new CliError("Provider is openrouter but OPENROUTER_API_KEY is not set or is not an sk-or- key.");
25
+ }
26
+ return "openrouter";
27
+ case "cloudflare":
28
+ if (!hasCloudflare) {
29
+ throw new CliError("Provider is cloudflare but CLOUDFLARE_API_TOKEN (or JEV_CLOUDFLARE_API_TOKEN) and CLOUDFLARE_ACCOUNT_ID are not both set.");
30
+ }
31
+ return "cloudflare";
32
+ case "auto":
33
+ if (hasTypesafe)
34
+ return "typesafe";
35
+ if (hasOpenRouter)
36
+ return "openrouter";
37
+ if (hasCloudflare)
38
+ return "cloudflare";
39
+ throw new CliError("No credentials found. Set TYPESAFE_API_KEY (https://console.typesafe.ai/settings/keys), " +
40
+ "OPENROUTER_API_KEY (sk-or-...), or CLOUDFLARE_API_TOKEN + CLOUDFLARE_ACCOUNT_ID.");
41
+ default: {
42
+ const never = explicit;
43
+ throw new CliError(`Unknown provider ${String(never)}`);
44
+ }
45
+ }
46
+ }
47
+ /** Model slug as each proxy expects it. */
48
+ export function providerModel(provider, model) {
49
+ if (provider === "openrouter") {
50
+ const effective = model === "jev-latest" ? OPENROUTER_LATEST : model;
51
+ return effective.startsWith("typesafe/") ? effective : `typesafe/${effective}`;
52
+ }
53
+ if (provider === "cloudflare") {
54
+ if (model.startsWith("typesafe/"))
55
+ return model;
56
+ return `typesafe/${model === "jev-latest" ? "jev" : model}`;
57
+ }
58
+ return model;
59
+ }
60
+ /** Build an `AskFn` bound to the resolved provider. */
61
+ export function createAsk(opts) {
62
+ const env = opts.env ?? process.env;
63
+ const provider = resolveProvider(env, opts.provider);
64
+ const fetchImpl = opts.fetch ?? globalThis.fetch;
65
+ const model = providerModel(provider, opts.model);
66
+ if (provider === "typesafe") {
67
+ const client = new TypeSafeClient({
68
+ apiKey: env.TYPESAFE_API_KEY,
69
+ baseURL: env.TYPESAFE_BASE_URL || undefined,
70
+ defaultModel: model,
71
+ timeout: opts.timeoutMs,
72
+ fetch: fetchImpl,
73
+ defaultHeaders: { "User-Agent": USER_AGENT },
74
+ });
75
+ return async (state, questions) => {
76
+ const response = await client.systemOne({ state: state, questions: questions, model }, { signal: opts.signal });
77
+ return {
78
+ answers: response.answers,
79
+ usage: {
80
+ input_tokens: response.usage?.input_tokens ?? 0,
81
+ output_tokens: response.usage?.output_tokens ?? 0,
82
+ },
83
+ provider,
84
+ model: response.model ?? model,
85
+ };
86
+ };
87
+ }
88
+ if (provider === "openrouter") {
89
+ return async (state, questions) => {
90
+ const response = await fetchWithTimeout(fetchImpl, "https://openrouter.ai/api/alpha/decisions", {
91
+ method: "POST",
92
+ headers: {
93
+ Authorization: `Bearer ${env.OPENROUTER_API_KEY}`,
94
+ "Content-Type": "application/json",
95
+ "HTTP-Referer": REFERER,
96
+ "X-Title": USER_AGENT,
97
+ },
98
+ body: JSON.stringify({ model, state, questions }),
99
+ }, opts.timeoutMs, opts.signal);
100
+ if (!response.ok) {
101
+ const body = await response.text().catch(() => "");
102
+ throw new CliError(`OpenRouter decisions API ${response.status}: ${body.slice(0, 300)}`);
103
+ }
104
+ const body = (await response.json());
105
+ return {
106
+ answers: body.answers ?? {},
107
+ usage: { input_tokens: body.usage?.input_tokens ?? 0, output_tokens: body.usage?.output_tokens ?? 0 },
108
+ provider,
109
+ model: body.model ?? model,
110
+ };
111
+ };
112
+ }
113
+ // Cloudflare Workers AI wraps the same contract in {model, input} and the
114
+ // v4 {result, success} envelope. Single alias; no version pinning.
115
+ return async (state, questions) => {
116
+ const response = await fetchWithTimeout(fetchImpl, `https://api.cloudflare.com/client/v4/accounts/${env.CLOUDFLARE_ACCOUNT_ID}/ai/run`, {
117
+ method: "POST",
118
+ headers: {
119
+ Authorization: `Bearer ${env.JEV_CLOUDFLARE_API_TOKEN || env.CLOUDFLARE_API_TOKEN}`,
120
+ "Content-Type": "application/json",
121
+ },
122
+ body: JSON.stringify({ model, input: { state, questions } }),
123
+ }, opts.timeoutMs, opts.signal);
124
+ const body = (await response.json().catch(() => ({})));
125
+ if (!response.ok || body.success === false) {
126
+ throw new CliError(`Cloudflare AI run ${response.status}: ${JSON.stringify(body.errors ?? body).slice(0, 300)}`);
127
+ }
128
+ const outer = body.result;
129
+ if (outer && typeof outer.state === "string" && outer.state !== "Completed") {
130
+ throw new CliError(`Cloudflare AI run state ${outer.state}: ${JSON.stringify(body.errors ?? []).slice(0, 300)}`);
131
+ }
132
+ const payload = outer?.result ?? outer ?? body;
133
+ return {
134
+ answers: payload.answers ?? {},
135
+ usage: {
136
+ input_tokens: payload.usage?.input_tokens ?? 0,
137
+ output_tokens: payload.usage?.output_tokens ?? 0,
138
+ },
139
+ provider,
140
+ model: payload.model ?? model,
141
+ };
142
+ };
143
+ }
144
+ async function fetchWithTimeout(fetchImpl, url, init, timeoutMs, outer) {
145
+ const signals = [AbortSignal.timeout(timeoutMs)];
146
+ if (outer)
147
+ signals.push(outer);
148
+ try {
149
+ return await fetchImpl(url, { ...init, signal: AbortSignal.any(signals) });
150
+ }
151
+ catch (err) {
152
+ if (err.name === "TimeoutError")
153
+ throw new CliError(`Request timed out after ${timeoutMs} ms.`);
154
+ throw err;
155
+ }
156
+ }
157
+ //# sourceMappingURL=provider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provider.js","sourceRoot":"","sources":["../src/provider.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,78 @@
1
+ {
2
+ "name": "jevctl",
3
+ "version": "0.1.0",
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
+ "type": "module",
6
+ "license": "MIT",
7
+ "author": "Nasr Shaer",
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "git+https://github.com/Nasrallah-AL/jev-cli.git"
11
+ },
12
+ "homepage": "https://github.com/Nasrallah-AL/jev-cli#readme",
13
+ "bugs": "https://github.com/Nasrallah-AL/jev-cli/issues",
14
+ "bin": {
15
+ "jev": "dist/cli.js"
16
+ },
17
+ "main": "dist/index.js",
18
+ "types": "dist/index.d.ts",
19
+ "exports": {
20
+ ".": {
21
+ "types": "./dist/index.d.ts",
22
+ "import": "./dist/index.js"
23
+ }
24
+ },
25
+ "files": [
26
+ "dist",
27
+ "README.md",
28
+ "LICENSE",
29
+ "NOTICE",
30
+ "CHANGELOG.md",
31
+ "SECURITY.md"
32
+ ],
33
+ "engines": {
34
+ "node": ">=20.12"
35
+ },
36
+ "scripts": {
37
+ "build": "tsc -p tsconfig.build.json",
38
+ "clean": "rm -rf dist",
39
+ "dev": "tsx src/cli.ts",
40
+ "typecheck": "tsc --noEmit",
41
+ "lint": "biome check .",
42
+ "lint:fix": "biome check --write .",
43
+ "test": "vitest run",
44
+ "test:watch": "vitest",
45
+ "test:coverage": "vitest run --coverage",
46
+ "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"
49
+ },
50
+ "keywords": [
51
+ "cli",
52
+ "typesafe",
53
+ "jev",
54
+ "system-one",
55
+ "ai",
56
+ "verification",
57
+ "guardrails",
58
+ "prompt-injection",
59
+ "semantic-search",
60
+ "fact-check"
61
+ ],
62
+ "dependencies": {
63
+ "@typesafe-ai/sdk": "^0.6.0",
64
+ "commander": "^15.0.0",
65
+ "zod": "^4.0.0"
66
+ },
67
+ "devDependencies": {
68
+ "@biomejs/biome": "^2.5.14",
69
+ "@types/node": "^22.0.0",
70
+ "@vitest/coverage-v8": "^5.0.1",
71
+ "tsx": "^4.23.13",
72
+ "typescript": "^5.9.0",
73
+ "vitest": "^5.0.1"
74
+ },
75
+ "publishConfig": {
76
+ "access": "public"
77
+ }
78
+ }