@mhingston5/jev-cli 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.
package/README.md CHANGED
@@ -118,6 +118,11 @@ console.log(response.answers);
118
118
  For dynamically constructed question definitions, `buildQuestion()` and `buildQuestions()` accept JSON-friendly specs. The package also exports `SystemOneLikeClient` so higher-level libraries can inject deterministic fixture clients in tests.
119
119
 
120
120
 
121
+ ## Agent skill
122
+
123
+ The npm package includes `skills/jev-cli/SKILL.md` for coding agents that need guidance on selecting Jev primitives, shaping state, batching questions, interpreting confidence, and using the CLI safely. It is intentionally CLI-focused; domain-specific packages such as `jev-agent-browser` keep their own skills.
124
+
125
+
121
126
  ## Development
122
127
 
123
128
  ```bash
package/dist/cli.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":""}
@@ -0,0 +1,41 @@
1
+ import type { SystemOneLikeClient, SystemOneRequest, SystemOneResponse } from "./types.js";
2
+ export declare const JEV_PROVIDERS: readonly ["typesafe", "vercel", "cloudflare", "custom"];
3
+ export type JevProvider = typeof JEV_PROVIDERS[number];
4
+ export interface JevClientOptions {
5
+ provider?: JevProvider;
6
+ apiKey?: string;
7
+ accountId?: string;
8
+ endpoint?: string;
9
+ model?: string;
10
+ timeoutMs?: number;
11
+ headers?: Record<string, string>;
12
+ fetchImpl?: typeof fetch;
13
+ }
14
+ export declare const DEFAULT_ENDPOINT = "https://api.typesafe.ai/v1/systemone";
15
+ export declare const VERCEL_ENDPOINT = "https://ai-gateway.vercel.sh/typesafe/v1/systemone";
16
+ export declare function resolveJevProvider(options?: JevClientOptions): JevProvider;
17
+ export declare function defaultModelForProvider(provider: JevProvider): string;
18
+ export declare function credentialEnvironmentForProvider(provider: JevProvider): string[];
19
+ export declare function defaultEndpointForProvider(provider: JevProvider, accountId?: string): string;
20
+ export declare class FetchJevClient implements SystemOneLikeClient {
21
+ private readonly endpoint;
22
+ private readonly apiKey;
23
+ private readonly model;
24
+ private readonly timeoutMs;
25
+ private readonly headers;
26
+ private readonly fetchImpl;
27
+ constructor(options?: JevClientOptions);
28
+ systemOne(request: SystemOneRequest): Promise<SystemOneResponse>;
29
+ }
30
+ export declare class CloudflareJevClient implements SystemOneLikeClient {
31
+ private readonly endpoint;
32
+ private readonly apiKey;
33
+ private readonly model;
34
+ private readonly timeoutMs;
35
+ private readonly headers;
36
+ private readonly fetchImpl;
37
+ constructor(options?: JevClientOptions);
38
+ systemOne(request: SystemOneRequest): Promise<SystemOneResponse>;
39
+ }
40
+ export declare function createJevClient(options?: JevClientOptions): SystemOneLikeClient;
41
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAE3F,eAAO,MAAM,aAAa,yDAA0D,CAAC;AACrF,MAAM,MAAM,WAAW,GAAG,OAAO,aAAa,CAAC,MAAM,CAAC,CAAC;AAGvD,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,EAAE,WAAW,CAAC;IACvB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;CAC1B;AAGD,eAAO,MAAM,gBAAgB,yCAAyC,CAAC;AACvE,eAAO,MAAM,eAAe,uDAAuD,CAAC;AAwBpF,wBAAgB,kBAAkB,CAAC,OAAO,GAAE,gBAAqB,GAAG,WAAW,CAK9E;AAGD,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,WAAW,GAAG,MAAM,CAarE;AAED,wBAAgB,gCAAgC,CAAC,QAAQ,EAAE,WAAW,GAAG,MAAM,EAAE,CAOhF;AAWD,wBAAgB,0BAA0B,CAAC,QAAQ,EAAE,WAAW,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,CAgB5F;AA8BD,qBAAa,cAAe,YAAW,mBAAmB;IACxD,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAqB;IAC5C,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAqB;IAC3C,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAyB;IACjD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAe;gBAE7B,OAAO,GAAE,gBAAqB;IASpC,SAAS,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,iBAAiB,CAAC;CAyBvE;AAED,qBAAa,mBAAoB,YAAW,mBAAmB;IAC7D,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAS;IAC/B,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAyB;IACjD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAe;gBAE7B,OAAO,GAAE,gBAAqB;IAWpC,SAAS,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,iBAAiB,CAAC;CAyBvE;AAED,wBAAgB,eAAe,CAAC,OAAO,GAAE,gBAAqB,GAAG,mBAAmB,CAWnF"}
@@ -0,0 +1,5 @@
1
+ export * from "./types.js";
2
+ export * from "./client.js";
3
+ export * from "./questions.js";
4
+ export { choice, noul, score, TypeSafeClient } from "@typesafe-ai/sdk";
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,gBAAgB,CAAC;AAC/B,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC"}
@@ -0,0 +1,22 @@
1
+ export type NoulQuestionSpec = {
2
+ type: "noul";
3
+ instructions: string;
4
+ labels?: {
5
+ true?: string;
6
+ false?: string;
7
+ };
8
+ };
9
+ export type ChoiceQuestionSpec = {
10
+ type: "choice";
11
+ instructions: string;
12
+ choices: Record<string, string | null>;
13
+ };
14
+ export type ScoreQuestionSpec = {
15
+ type: "score";
16
+ instructions: string;
17
+ levels: string[];
18
+ };
19
+ export type QuestionSpec = NoulQuestionSpec | ChoiceQuestionSpec | ScoreQuestionSpec;
20
+ export declare function buildQuestion(spec: QuestionSpec): unknown;
21
+ export declare function buildQuestions(specs: Record<string, QuestionSpec>): Record<string, unknown>;
22
+ //# sourceMappingURL=questions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"questions.d.ts","sourceRoot":"","sources":["../src/questions.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,gBAAgB,GAAG;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CAC5C,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,IAAI,EAAE,QAAQ,CAAC;IACf,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC,CAAC;CACxC,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG;IAC9B,IAAI,EAAE,OAAO,CAAC;IACd,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG,gBAAgB,GAAG,kBAAkB,GAAG,iBAAiB,CAAC;AAMrF,wBAAgB,aAAa,CAAC,IAAI,EAAE,YAAY,GAAG,OAAO,CAuBzD;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAS3F"}
@@ -0,0 +1,17 @@
1
+ export interface SystemOneRequest {
2
+ model?: string;
3
+ state: unknown;
4
+ questions: unknown;
5
+ }
6
+ export interface SystemOneResponse {
7
+ model: string;
8
+ answers: Record<string, unknown>;
9
+ usage?: {
10
+ input_tokens?: number;
11
+ output_tokens?: number;
12
+ };
13
+ }
14
+ export interface SystemOneLikeClient {
15
+ systemOne(request: SystemOneRequest): Promise<SystemOneResponse>;
16
+ }
17
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,gBAAgB;IAC/B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,OAAO,CAAC;IACf,SAAS,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjC,KAAK,CAAC,EAAE;QACN,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,aAAa,CAAC,EAAE,MAAM,CAAC;KACxB,CAAC;CACH;AAED,MAAM,WAAW,mBAAmB;IAClC,SAAS,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAC;CAClE"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mhingston5/jev-cli",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "description": "Provider-agnostic CLI and client for TypeSafe AI Jev",
5
5
  "license": "MIT",
6
6
  "author": "Mark Hingston",
@@ -24,6 +24,7 @@
24
24
  },
25
25
  "files": [
26
26
  "dist",
27
+ "skills",
27
28
  "README.md",
28
29
  "LICENSE"
29
30
  ],
@@ -0,0 +1,187 @@
1
+ ---
2
+ name: jev-cli
3
+ description: Use the Jev CLI for bounded semantic judgments with Noul, Choice, Score, or batched questions. Use when classifying, scoring, routing, verifying, or diagnosing structured Jev decisions from the command line.
4
+ ---
5
+
6
+ # Jev CLI
7
+
8
+ Use `jev` for small, bounded semantic judgments. Jev should decide among explicit alternatives or estimate a crisp proposition; code should own control flow, arithmetic, thresholds, side effects, and policy.
9
+
10
+ ## Choose the right primitive
11
+
12
+ - **Noul** — a crisp yes/no proposition where the probability itself is useful.
13
+ - **Choice** — one answer from a known unordered set.
14
+ - **Score** — one position on an ordered qualitative scale.
15
+ - **Batch** — several independent questions over the same state. Prefer this when questions share context.
16
+
17
+ Do not use Jev for open-ended generation, planning, arithmetic, counting, date comparison, or multi-step reasoning. Compute deterministic facts first and ask Jev only for the semantic judgment.
18
+
19
+ ## Prepare state
20
+
21
+ Send only the evidence needed by the question.
22
+
23
+ Prefer structured JSON so the question can refer to explicit fields. Remove unrelated context and compute deterministic values before invoking Jev.
24
+
25
+ Good:
26
+
27
+ ```json
28
+ {"ticket":{"text":"I was charged twice and need one charge refunded today."}}
29
+ ```
30
+
31
+ Avoid sending an entire conversation, document, or application state when one field is enough.
32
+
33
+ ## Write questions
34
+
35
+ Make each question atomic and literal.
36
+
37
+ Good:
38
+
39
+ ```text
40
+ Does `ticket.text` explicitly request a refund?
41
+ ```
42
+
43
+ Avoid:
44
+
45
+ ```text
46
+ Analyze this ticket and decide what we should do.
47
+ ```
48
+
49
+ Keep business policy outside the question. If a refund request above a threshold should route to billing, apply that rule in caller code.
50
+
51
+ ### Noul
52
+
53
+ Use for a clear proposition:
54
+
55
+ ```bash
56
+ jev noul \
57
+ --state '{"ticket":{"text":"Please refund the duplicate charge today."}}' \
58
+ --question 'Does `ticket.text` explicitly request a refund?' \
59
+ --answer-only
60
+ ```
61
+
62
+ A value near 0.5 means uncertainty. It does not mean "medium". Use Score for degrees.
63
+
64
+ ### Choice
65
+
66
+ Use when the answer belongs to a bounded taxonomy:
67
+
68
+ ```bash
69
+ jev choice \
70
+ --state '{"ticket":{"text":"I was charged twice."}}' \
71
+ --question 'Which team should handle `ticket.text`?' \
72
+ --choices '{"billing":"Charges, invoices, refunds, or subscriptions","technical":"Bugs or outages","other":"Anything else"}'
73
+ ```
74
+
75
+ Add `other` or an equivalent fallback when the taxonomy may be incomplete. Make nearby options contrastive.
76
+
77
+ ### Score
78
+
79
+ Use for an ordered scale whose levels can be described distinctly:
80
+
81
+ ```bash
82
+ jev score \
83
+ --state '{"impact":"Checkout is unavailable and there is no workaround."}' \
84
+ --question 'How severe is the reported impact?' \
85
+ --levels '["Cosmetic or negligible impact","Degraded but a workaround exists","Blocking with no workaround"]'
86
+ ```
87
+
88
+ Describe concrete situations rather than labels such as "low", "medium", and "high" when those labels alone are ambiguous.
89
+
90
+ ## Batch shared state
91
+
92
+ Questions in one request share the same state. Prefer one batch over several sequential CLI calls when the questions are independent.
93
+
94
+ ```json
95
+ {
96
+ "refund_requested": {
97
+ "type": "noul",
98
+ "instructions": "Does `ticket.text` explicitly request a refund?"
99
+ },
100
+ "queue": {
101
+ "type": "choice",
102
+ "instructions": "Which team should handle `ticket.text`?",
103
+ "choices": {
104
+ "billing": "Charges, invoices, refunds, or subscriptions",
105
+ "technical": "Bugs or outages",
106
+ "other": "Anything else"
107
+ }
108
+ },
109
+ "severity": {
110
+ "type": "score",
111
+ "instructions": "How severe is the impact described in `ticket.text`?",
112
+ "levels": [
113
+ "Cosmetic or negligible impact",
114
+ "Degraded but a workaround exists",
115
+ "Blocking with no workaround"
116
+ ]
117
+ }
118
+ }
119
+ ```
120
+
121
+ Save that as `questions.json` and run:
122
+
123
+ ```bash
124
+ jev run \
125
+ --state-file ticket.json \
126
+ --questions-file questions.json
127
+ ```
128
+
129
+ Use a second Jev request only when code genuinely cannot construct it until after seeing the first answer.
130
+
131
+ ## Interpret answers safely
132
+
133
+ The top answer is not proof of correctness.
134
+
135
+ - Inspect probabilities when a decision matters.
136
+ - Treat confidence as evidence about the answer distribution, not guaranteed accuracy.
137
+ - Set thresholds in caller code.
138
+ - Use a review, confirmation, or fallback path below the threshold.
139
+ - Raise thresholds as the cost of a wrong action increases.
140
+ - Validate thresholds against labelled examples from the real task.
141
+
142
+ Never hide policy inside question wording merely to force a desired answer.
143
+
144
+ ## Improve weak judgments
145
+
146
+ When a result is wrong or uncertain, isolate the failing question first.
147
+
148
+ - **Choice overlaps** → make option descriptions more contrastive; add `other` if needed.
149
+ - **Noul near 0.5** → make the condition more literal and observable.
150
+ - **Score clusters in the middle** → rewrite levels as distinct concrete situations.
151
+ - **Accuracy falls with larger inputs** → remove irrelevant state.
152
+ - **Counting, sums, dates, or numeric comparisons fail** → move the deterministic operation to code.
153
+ - **One wording fix breaks another case** → the question may contain multiple judgments; split it.
154
+ - **Answers are right but the final action is wrong** → change policy, weights, or thresholds in code rather than rewriting the question.
155
+
156
+ Revise against labelled examples. Do not treat higher confidence alone as evidence of improvement.
157
+
158
+ ## Provider checks
159
+
160
+ Run `jev doctor` to verify provider/model configuration and whether the expected credential environment variables are present.
161
+
162
+ ```bash
163
+ jev doctor
164
+ jev doctor --provider vercel
165
+ ```
166
+
167
+ Credentials belong in environment variables or a secret manager, never command-line arguments.
168
+
169
+ ## Checklist
170
+
171
+ Before relying on a Jev decision:
172
+
173
+ - Each question asks one semantic property.
174
+ - The primitive matches how caller code uses the answer.
175
+ - State contains only necessary evidence.
176
+ - Deterministic computation stays in code.
177
+ - Independent questions sharing state are batched.
178
+ - Choice taxonomies have an appropriate fallback when incomplete.
179
+ - Score levels are concrete and distinguishable.
180
+ - Thresholds and side effects live outside Jev.
181
+ - Low-confidence decisions have a safe fallback.
182
+ - Changes are evaluated on labelled examples.
183
+
184
+ ## Further reading
185
+
186
+ This skill is intentionally CLI-focused. For deeper Jev question-design patterns, see TypeSafe AI's Jev documentation and the independent `building-with-jev-skill` reference:
187
+ https://github.com/dbreunig/building-with-jev-skill/tree/main/skills/jev