jev-affected 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 (47) hide show
  1. package/.env.example +3 -0
  2. package/CHANGELOG.md +8 -0
  3. package/CODE_OF_CONDUCT.md +7 -0
  4. package/CONTRIBUTING.md +16 -0
  5. package/EVALUATION.md +77 -0
  6. package/LICENSE +21 -0
  7. package/NOTICE +6 -0
  8. package/README.md +201 -0
  9. package/SECURITY.md +21 -0
  10. package/assets/README.md +5 -0
  11. package/assets/demo.gif +0 -0
  12. package/assets/demo.mp4 +0 -0
  13. package/assets/favicon.svg +1 -0
  14. package/assets/logo-dark.svg +1 -0
  15. package/assets/logo-mark.svg +1 -0
  16. package/assets/logo-wordmark.svg +1 -0
  17. package/assets/logo.svg +1 -0
  18. package/assets/social-card.png +0 -0
  19. package/dist/cli.d.ts +2 -0
  20. package/dist/cli.js +214 -0
  21. package/dist/config.d.ts +41 -0
  22. package/dist/config.js +97 -0
  23. package/dist/eval.d.ts +41 -0
  24. package/dist/eval.js +96 -0
  25. package/dist/executor.d.ts +6 -0
  26. package/dist/executor.js +68 -0
  27. package/dist/git.d.ts +21 -0
  28. package/dist/git.js +102 -0
  29. package/dist/index.d.ts +5 -0
  30. package/dist/index.js +5 -0
  31. package/dist/planner.d.ts +37 -0
  32. package/dist/planner.js +132 -0
  33. package/dist/provider.d.ts +21 -0
  34. package/dist/provider.js +28 -0
  35. package/evals/fixtures/api-response-field.json +53 -0
  36. package/evals/fixtures/auth-session-ttl.json +53 -0
  37. package/evals/fixtures/comment-only.json +53 -0
  38. package/evals/fixtures/db-schema.json +53 -0
  39. package/evals/fixtures/docs-only.json +53 -0
  40. package/evals/fixtures/logging-only.json +53 -0
  41. package/evals/fixtures/performance.json +53 -0
  42. package/examples/basic/jev-affected.yml +16 -0
  43. package/package.json +84 -0
  44. package/skills/jev-affected/SKILL.md +51 -0
  45. package/skills/jev-affected/agents/openai.yaml +7 -0
  46. package/skills/jev-affected/assets/icon-large.svg +4 -0
  47. package/skills/jev-affected/assets/icon-small.svg +4 -0
@@ -0,0 +1,28 @@
1
+ import { noul, TypeSafeClient } from "@typesafe-ai/sdk";
2
+ export class JevProvider {
3
+ async analyze(input) {
4
+ const client = new TypeSafeClient({
5
+ logLevel: "off",
6
+ timeout: input.timeoutMs,
7
+ retry: { maxRetries: 0 },
8
+ });
9
+ const response = await client.systemOne({
10
+ model: input.model,
11
+ state: {
12
+ base: input.state.base,
13
+ head: input.state.head,
14
+ files: input.state.files.map((f) => ({ ...f })),
15
+ diff: input.state.diff,
16
+ },
17
+ questions: Object.fromEntries(Object.entries(input.questions).map(([id, q]) => [id, noul(q)])),
18
+ });
19
+ return {
20
+ model: response.model,
21
+ probabilities: Object.fromEntries(Object.entries(response.answers).map(([id, a]) => [
22
+ id,
23
+ a.type === "noul" ? a.noul : Number.NaN,
24
+ ])),
25
+ usage: response.usage,
26
+ };
27
+ }
28
+ }
@@ -0,0 +1,53 @@
1
+ {
2
+ "name": "api-response-field",
3
+ "provenance": "Synthetic SDK-shaped responses, not recorded Jev output; live model quality is unverified.",
4
+ "config": {
5
+ "version": 1,
6
+ "tasks": {
7
+ "auth": {
8
+ "command": "node -e \"console.log('auth tests')\"",
9
+ "when": "Could authentication, session or cookie behavior change?"
10
+ },
11
+ "sdk": {
12
+ "command": "node -e \"console.log('SDK generation')\"",
13
+ "when": "Could the public API contract change?"
14
+ },
15
+ "db": {
16
+ "command": "node -e \"console.log('database tests')\"",
17
+ "when": "Could database schemas or persistence change?"
18
+ },
19
+ "benchmark": {
20
+ "command": "node -e \"console.log('benchmark')\"",
21
+ "when": "Could a performance-sensitive execution path materially change?"
22
+ }
23
+ }
24
+ },
25
+ "state": {
26
+ "base": "fixture-base",
27
+ "head": "fixture-head",
28
+ "files": [
29
+ {
30
+ "path": "src/api.ts",
31
+ "status": "M"
32
+ }
33
+ ],
34
+ "diff": "diff --git a/src/api.ts b/src/api.ts\n--- a/src/api.ts\n+++ b/src/api.ts\n@@ -1 +1 @@\n-return {id}\n+return {id, name}\n",
35
+ "incomplete": false,
36
+ "warnings": []
37
+ },
38
+ "response": {
39
+ "model": "jev-1.13.0",
40
+ "probabilities": {
41
+ "auth": 0.01,
42
+ "sdk": 0.95,
43
+ "db": 0.01,
44
+ "benchmark": 0.01
45
+ }
46
+ },
47
+ "expected": {
48
+ "auth": "skip",
49
+ "sdk": "run",
50
+ "db": "skip",
51
+ "benchmark": "skip"
52
+ }
53
+ }
@@ -0,0 +1,53 @@
1
+ {
2
+ "name": "auth-session-ttl",
3
+ "provenance": "Synthetic SDK-shaped responses, not recorded Jev output; live model quality is unverified.",
4
+ "config": {
5
+ "version": 1,
6
+ "tasks": {
7
+ "auth": {
8
+ "command": "node -e \"console.log('auth tests')\"",
9
+ "when": "Could authentication, session or cookie behavior change?"
10
+ },
11
+ "sdk": {
12
+ "command": "node -e \"console.log('SDK generation')\"",
13
+ "when": "Could the public API contract change?"
14
+ },
15
+ "db": {
16
+ "command": "node -e \"console.log('database tests')\"",
17
+ "when": "Could database schemas or persistence change?"
18
+ },
19
+ "benchmark": {
20
+ "command": "node -e \"console.log('benchmark')\"",
21
+ "when": "Could a performance-sensitive execution path materially change?"
22
+ }
23
+ }
24
+ },
25
+ "state": {
26
+ "base": "fixture-base",
27
+ "head": "fixture-head",
28
+ "files": [
29
+ {
30
+ "path": "src/auth.ts",
31
+ "status": "M"
32
+ }
33
+ ],
34
+ "diff": "diff --git a/src/auth.ts b/src/auth.ts\n--- a/src/auth.ts\n+++ b/src/auth.ts\n@@ -1 +1 @@\n-const TTL = 3600\n+const TTL = 86400\n",
35
+ "incomplete": false,
36
+ "warnings": []
37
+ },
38
+ "response": {
39
+ "model": "jev-1.13.0",
40
+ "probabilities": {
41
+ "auth": 0.95,
42
+ "sdk": 0.01,
43
+ "db": 0.01,
44
+ "benchmark": 0.01
45
+ }
46
+ },
47
+ "expected": {
48
+ "auth": "run",
49
+ "sdk": "skip",
50
+ "db": "skip",
51
+ "benchmark": "skip"
52
+ }
53
+ }
@@ -0,0 +1,53 @@
1
+ {
2
+ "name": "comment-only",
3
+ "provenance": "Synthetic SDK-shaped responses, not recorded Jev output; live model quality is unverified.",
4
+ "config": {
5
+ "version": 1,
6
+ "tasks": {
7
+ "auth": {
8
+ "command": "node -e \"console.log('auth tests')\"",
9
+ "when": "Could authentication, session or cookie behavior change?"
10
+ },
11
+ "sdk": {
12
+ "command": "node -e \"console.log('SDK generation')\"",
13
+ "when": "Could the public API contract change?"
14
+ },
15
+ "db": {
16
+ "command": "node -e \"console.log('database tests')\"",
17
+ "when": "Could database schemas or persistence change?"
18
+ },
19
+ "benchmark": {
20
+ "command": "node -e \"console.log('benchmark')\"",
21
+ "when": "Could a performance-sensitive execution path materially change?"
22
+ }
23
+ }
24
+ },
25
+ "state": {
26
+ "base": "fixture-base",
27
+ "head": "fixture-head",
28
+ "files": [
29
+ {
30
+ "path": "src/auth.ts",
31
+ "status": "M"
32
+ }
33
+ ],
34
+ "diff": "diff --git a/src/auth.ts b/src/auth.ts\n--- a/src/auth.ts\n+++ b/src/auth.ts\n@@ -1 +1 @@\n-// session\n+// session duration\n",
35
+ "incomplete": false,
36
+ "warnings": []
37
+ },
38
+ "response": {
39
+ "model": "jev-1.13.0",
40
+ "probabilities": {
41
+ "auth": 0.01,
42
+ "sdk": 0.01,
43
+ "db": 0.01,
44
+ "benchmark": 0.01
45
+ }
46
+ },
47
+ "expected": {
48
+ "auth": "skip",
49
+ "sdk": "skip",
50
+ "db": "skip",
51
+ "benchmark": "skip"
52
+ }
53
+ }
@@ -0,0 +1,53 @@
1
+ {
2
+ "name": "db-schema",
3
+ "provenance": "Synthetic SDK-shaped responses, not recorded Jev output; live model quality is unverified.",
4
+ "config": {
5
+ "version": 1,
6
+ "tasks": {
7
+ "auth": {
8
+ "command": "node -e \"console.log('auth tests')\"",
9
+ "when": "Could authentication, session or cookie behavior change?"
10
+ },
11
+ "sdk": {
12
+ "command": "node -e \"console.log('SDK generation')\"",
13
+ "when": "Could the public API contract change?"
14
+ },
15
+ "db": {
16
+ "command": "node -e \"console.log('database tests')\"",
17
+ "when": "Could database schemas or persistence change?"
18
+ },
19
+ "benchmark": {
20
+ "command": "node -e \"console.log('benchmark')\"",
21
+ "when": "Could a performance-sensitive execution path materially change?"
22
+ }
23
+ }
24
+ },
25
+ "state": {
26
+ "base": "fixture-base",
27
+ "head": "fixture-head",
28
+ "files": [
29
+ {
30
+ "path": "schema.sql",
31
+ "status": "M"
32
+ }
33
+ ],
34
+ "diff": "diff --git a/schema.sql b/schema.sql\n--- a/schema.sql\n+++ b/schema.sql\n@@ -1 +1 @@\n-name TEXT\n+name VARCHAR(100)\n",
35
+ "incomplete": false,
36
+ "warnings": []
37
+ },
38
+ "response": {
39
+ "model": "jev-1.13.0",
40
+ "probabilities": {
41
+ "auth": 0.01,
42
+ "sdk": 0.01,
43
+ "db": 0.95,
44
+ "benchmark": 0.01
45
+ }
46
+ },
47
+ "expected": {
48
+ "auth": "skip",
49
+ "sdk": "skip",
50
+ "db": "run",
51
+ "benchmark": "skip"
52
+ }
53
+ }
@@ -0,0 +1,53 @@
1
+ {
2
+ "name": "docs-only",
3
+ "provenance": "Synthetic SDK-shaped responses, not recorded Jev output; live model quality is unverified.",
4
+ "config": {
5
+ "version": 1,
6
+ "tasks": {
7
+ "auth": {
8
+ "command": "node -e \"console.log('auth tests')\"",
9
+ "when": "Could authentication, session or cookie behavior change?"
10
+ },
11
+ "sdk": {
12
+ "command": "node -e \"console.log('SDK generation')\"",
13
+ "when": "Could the public API contract change?"
14
+ },
15
+ "db": {
16
+ "command": "node -e \"console.log('database tests')\"",
17
+ "when": "Could database schemas or persistence change?"
18
+ },
19
+ "benchmark": {
20
+ "command": "node -e \"console.log('benchmark')\"",
21
+ "when": "Could a performance-sensitive execution path materially change?"
22
+ }
23
+ }
24
+ },
25
+ "state": {
26
+ "base": "fixture-base",
27
+ "head": "fixture-head",
28
+ "files": [
29
+ {
30
+ "path": "README.md",
31
+ "status": "M"
32
+ }
33
+ ],
34
+ "diff": "diff --git a/README.md b/README.md\n--- a/README.md\n+++ b/README.md\n@@ -1 +1 @@\n-Install\n+Installation\n",
35
+ "incomplete": false,
36
+ "warnings": []
37
+ },
38
+ "response": {
39
+ "model": "jev-1.13.0",
40
+ "probabilities": {
41
+ "auth": 0.01,
42
+ "sdk": 0.01,
43
+ "db": 0.01,
44
+ "benchmark": 0.01
45
+ }
46
+ },
47
+ "expected": {
48
+ "auth": "skip",
49
+ "sdk": "skip",
50
+ "db": "skip",
51
+ "benchmark": "skip"
52
+ }
53
+ }
@@ -0,0 +1,53 @@
1
+ {
2
+ "name": "logging-only",
3
+ "provenance": "Synthetic SDK-shaped responses, not recorded Jev output; live model quality is unverified.",
4
+ "config": {
5
+ "version": 1,
6
+ "tasks": {
7
+ "auth": {
8
+ "command": "node -e \"console.log('auth tests')\"",
9
+ "when": "Could authentication, session or cookie behavior change?"
10
+ },
11
+ "sdk": {
12
+ "command": "node -e \"console.log('SDK generation')\"",
13
+ "when": "Could the public API contract change?"
14
+ },
15
+ "db": {
16
+ "command": "node -e \"console.log('database tests')\"",
17
+ "when": "Could database schemas or persistence change?"
18
+ },
19
+ "benchmark": {
20
+ "command": "node -e \"console.log('benchmark')\"",
21
+ "when": "Could a performance-sensitive execution path materially change?"
22
+ }
23
+ }
24
+ },
25
+ "state": {
26
+ "base": "fixture-base",
27
+ "head": "fixture-head",
28
+ "files": [
29
+ {
30
+ "path": "src/log.ts",
31
+ "status": "M"
32
+ }
33
+ ],
34
+ "diff": "diff --git a/src/log.ts b/src/log.ts\n--- a/src/log.ts\n+++ b/src/log.ts\n@@ -1 +1 @@\n-logger.info(\"start\")\n+logger.info(\"started\")\n",
35
+ "incomplete": false,
36
+ "warnings": []
37
+ },
38
+ "response": {
39
+ "model": "jev-1.13.0",
40
+ "probabilities": {
41
+ "auth": 0.01,
42
+ "sdk": 0.01,
43
+ "db": 0.01,
44
+ "benchmark": 0.01
45
+ }
46
+ },
47
+ "expected": {
48
+ "auth": "skip",
49
+ "sdk": "skip",
50
+ "db": "skip",
51
+ "benchmark": "skip"
52
+ }
53
+ }
@@ -0,0 +1,53 @@
1
+ {
2
+ "name": "performance",
3
+ "provenance": "Synthetic SDK-shaped responses, not recorded Jev output; live model quality is unverified.",
4
+ "config": {
5
+ "version": 1,
6
+ "tasks": {
7
+ "auth": {
8
+ "command": "node -e \"console.log('auth tests')\"",
9
+ "when": "Could authentication, session or cookie behavior change?"
10
+ },
11
+ "sdk": {
12
+ "command": "node -e \"console.log('SDK generation')\"",
13
+ "when": "Could the public API contract change?"
14
+ },
15
+ "db": {
16
+ "command": "node -e \"console.log('database tests')\"",
17
+ "when": "Could database schemas or persistence change?"
18
+ },
19
+ "benchmark": {
20
+ "command": "node -e \"console.log('benchmark')\"",
21
+ "when": "Could a performance-sensitive execution path materially change?"
22
+ }
23
+ }
24
+ },
25
+ "state": {
26
+ "base": "fixture-base",
27
+ "head": "fixture-head",
28
+ "files": [
29
+ {
30
+ "path": "src/search.ts",
31
+ "status": "M"
32
+ }
33
+ ],
34
+ "diff": "diff --git a/src/search.ts b/src/search.ts\n--- a/src/search.ts\n+++ b/src/search.ts\n@@ -1 +1 @@\n-items.find(predicate)\n+index.get(key)\n",
35
+ "incomplete": false,
36
+ "warnings": []
37
+ },
38
+ "response": {
39
+ "model": "jev-1.13.0",
40
+ "probabilities": {
41
+ "auth": 0.01,
42
+ "sdk": 0.01,
43
+ "db": 0.01,
44
+ "benchmark": 0.95
45
+ }
46
+ },
47
+ "expected": {
48
+ "auth": "skip",
49
+ "sdk": "skip",
50
+ "db": "skip",
51
+ "benchmark": "run"
52
+ }
53
+ }
@@ -0,0 +1,16 @@
1
+ version: 1
2
+ defaults:
3
+ skipBelow: 0.10
4
+ tasks:
5
+ auth-e2e:
6
+ command: npm run test:auth
7
+ when: Could authentication, authorization, sessions, cookies or login behavior change?
8
+ api-contract:
9
+ command: npm run test:contract
10
+ when: Could a public API request, response, status code or header change?
11
+ sdk:
12
+ command: npm run generate:sdk
13
+ when: Could the public API contract change?
14
+ typecheck:
15
+ command: npm run typecheck
16
+ always: true
package/package.json ADDED
@@ -0,0 +1,84 @@
1
+ {
2
+ "name": "jev-affected",
3
+ "version": "0.1.0",
4
+ "description": "Semantic task routing for software development, powered by Jev.",
5
+ "type": "module",
6
+ "license": "MIT",
7
+ "author": "jammaru",
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "git+https://github.com/jammaru/jev-affected.git"
11
+ },
12
+ "homepage": "https://github.com/jammaru/jev-affected#readme",
13
+ "bugs": {
14
+ "url": "https://github.com/jammaru/jev-affected/issues"
15
+ },
16
+ "keywords": [
17
+ "jev",
18
+ "testing",
19
+ "ci",
20
+ "semantic",
21
+ "task-runner",
22
+ "developer-tools"
23
+ ],
24
+ "engines": {
25
+ "node": ">=20"
26
+ },
27
+ "packageManager": "pnpm@10.11.0",
28
+ "bin": {
29
+ "jev-affected": "dist/cli.js"
30
+ },
31
+ "exports": {
32
+ ".": {
33
+ "types": "./dist/index.d.ts",
34
+ "import": "./dist/index.js"
35
+ }
36
+ },
37
+ "files": [
38
+ "dist",
39
+ "assets",
40
+ "README.md",
41
+ "LICENSE",
42
+ "NOTICE",
43
+ "examples",
44
+ "CHANGELOG.md",
45
+ "CONTRIBUTING.md",
46
+ "SECURITY.md",
47
+ "CODE_OF_CONDUCT.md",
48
+ "EVALUATION.md",
49
+ ".env.example",
50
+ "evals",
51
+ "skills"
52
+ ],
53
+ "scripts": {
54
+ "build": "tsc",
55
+ "typecheck": "tsc --noEmit",
56
+ "test": "vitest run",
57
+ "lint": "biome check .",
58
+ "format": "biome check --write .",
59
+ "smoke": "node scripts/smoke.mjs",
60
+ "eval": "node dist/cli.js eval",
61
+ "eval:live": "node dist/cli.js eval --live",
62
+ "pretest": "pnpm build",
63
+ "demo": "node scripts/demo.mjs",
64
+ "prepack": "tsc"
65
+ },
66
+ "dependencies": {
67
+ "@typesafe-ai/sdk": "^0.6.0",
68
+ "dotenv": "^17.2.2",
69
+ "picomatch": "^4.0.7",
70
+ "yaml": "^2.9.1",
71
+ "zod": "^4.6.5"
72
+ },
73
+ "devDependencies": {
74
+ "@biomejs/biome": "^2.5.14",
75
+ "@changesets/cli": "^2.31.1",
76
+ "@types/node": "^22.20.4",
77
+ "@types/picomatch": "^4.0.3",
78
+ "typescript": "^7.0.2",
79
+ "vitest": "^3.2.7"
80
+ },
81
+ "publishConfig": {
82
+ "access": "public"
83
+ }
84
+ }
@@ -0,0 +1,51 @@
1
+ ---
2
+ name: jev-affected
3
+ description: Use jev-affected to inspect committed Git changes, create semantic task plans, explain decisions, and run selected repository checks. Apply when a repository contains jev-affected.yml or the user asks which tests, builds, benchmarks, or code-generation tasks a change affects semantically.
4
+ ---
5
+
6
+ # Jev Affected
7
+
8
+ Use the repository-installed CLI. Prefer `pnpm exec jev-affected` in pnpm
9
+ projects and `npx jev-affected` elsewhere.
10
+
11
+ ## Workflow
12
+
13
+ 1. Confirm the current directory is a Git repository and locate
14
+ `jev-affected.yml`. Run `jev-affected init` only when setup is requested and no
15
+ configuration exists.
16
+ 2. Ensure the relevant edits are committed. Version 0.1 compares commits and does
17
+ not include working-tree changes.
18
+ 3. On first use, or when privacy matters, run
19
+ `jev-affected inspect --base <ref>`. This previews the sanitized input locally
20
+ without sending a request.
21
+ 4. Run `jev-affected plan --json --base <ref>` and use its task decisions as the
22
+ record of what should run. Do not invent task reasons or commands.
23
+ 5. Run `jev-affected run --base <ref>` only when execution is requested. Commands
24
+ come from the repository configuration and should be treated as repository
25
+ code.
26
+ 6. Report the selected and skipped task counts, actual model version, warnings,
27
+ fallback decisions, and any failed task commands.
28
+
29
+ Use an explicit base ref in CI and shallow clones. Fetch enough history for Git to
30
+ compute the merge base.
31
+
32
+ ## Credentials and data
33
+
34
+ Set `TYPESAFE_API_KEY` in the process environment or a repository-local `.env`
35
+ file. Never print the value, commit `.env`, or store the key in
36
+ `jev-affected.yml`. An existing process environment value takes precedence over
37
+ `.env`.
38
+
39
+ `inspect` stays local. `plan`, `why`, and `run` can send the sanitized committed
40
+ diff and configured semantic questions to the provider. Review `inspect` output
41
+ before the first request when the repository may contain sensitive material.
42
+
43
+ ## Decision invariants
44
+
45
+ - A valid probability strictly below `skipBelow` produces SKIP.
46
+ - Equality with the threshold produces RUN.
47
+ - Provider errors, timeouts, and invalid answers produce RUN for candidates.
48
+ - `always: true` and `allowSkip: false` protect mandatory tasks.
49
+ - Exit code `0` means success, `1` means an executed task or evaluation failed,
50
+ `2` means a usage, configuration, base, or doctor error, and `3` means an
51
+ internal or I/O failure.
@@ -0,0 +1,7 @@
1
+ interface:
2
+ display_name: "jev-affected"
3
+ short_description: "Plan semantic checks for committed code changes"
4
+ icon_small: "../assets/icon-small.svg"
5
+ icon_large: "../assets/icon-large.svg"
6
+ brand_color: "#DAFB73"
7
+ default_prompt: "Use $jev-affected to inspect my committed changes, plan affected tasks, and run the selected checks."
@@ -0,0 +1,4 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" role="img" aria-label="jev-affected">
2
+ <rect width="512" height="512" rx="112" fill="#111312"/>
3
+ <path d="M132 144h72v160c0 45-27 72-72 72h-28v-64h18c12 0 18-7 18-23V144zm132 0h144v64h-80v36h72v56h-72v20h80v64H264V144z" fill="#DAFB73"/>
4
+ </svg>
@@ -0,0 +1,4 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" role="img" aria-label="jev-affected">
2
+ <rect width="64" height="64" rx="14" fill="#111312"/>
3
+ <path d="M17 19h9v20c0 5-3 9-9 9h-3v-8h2c1 0 2-1 2-3V19zm15 0h18v8H40v4h9v7h-9v3h10v8H32V19z" fill="#DAFB73"/>
4
+ </svg>