jev-agent-tools 0.1.4 → 0.3.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 (180) hide show
  1. package/CHANGELOG.md +106 -1
  2. package/CONTRIBUTING.md +43 -0
  3. package/README.md +58 -17
  4. package/SECURITY.md +43 -0
  5. package/dist/adapters/analysis-context.js +75 -0
  6. package/dist/adapters/ask-files.js +198 -0
  7. package/dist/adapters/ask-proof.js +200 -0
  8. package/dist/adapters/ask-syntax.js +385 -0
  9. package/dist/adapters/canonical-path.js +17 -0
  10. package/dist/adapters/command.js +234 -0
  11. package/dist/adapters/docs.js +192 -0
  12. package/dist/adapters/evidence-context.js +119 -0
  13. package/dist/adapters/exec.js +207 -0
  14. package/dist/adapters/files.js +418 -0
  15. package/dist/adapters/find.js +150 -0
  16. package/dist/adapters/git-base.js +32 -0
  17. package/dist/adapters/git-inventory.js +71 -0
  18. package/dist/adapters/git.js +483 -0
  19. package/dist/adapters/locate-file.js +197 -0
  20. package/dist/adapters/output-lines.js +46 -0
  21. package/dist/adapters/private-storage.js +106 -0
  22. package/dist/adapters/risk-callers.js +429 -0
  23. package/dist/adapters/runner-version.js +78 -0
  24. package/dist/adapters/shell.js +92 -0
  25. package/dist/adapters/syntax.js +187 -0
  26. package/dist/adapters/test-inventory.js +139 -0
  27. package/dist/adapters/usage.js +20 -0
  28. package/dist/adapters/utf8.js +47 -0
  29. package/dist/configuration.js +267 -0
  30. package/dist/constants.js +140 -0
  31. package/dist/core/ask-closure.js +282 -0
  32. package/dist/core/ask-proof.js +1 -0
  33. package/dist/core/ask-references.js +278 -0
  34. package/dist/core/asks.js +507 -0
  35. package/dist/core/batches.js +65 -0
  36. package/dist/core/command-output.js +224 -0
  37. package/dist/core/diff.js +178 -0
  38. package/dist/core/docs.js +302 -0
  39. package/dist/core/find.js +108 -0
  40. package/dist/core/git.js +1 -0
  41. package/dist/core/imports.js +550 -0
  42. package/dist/core/integrity.js +45 -0
  43. package/dist/core/lexical.js +132 -0
  44. package/dist/core/locate.js +169 -0
  45. package/dist/core/output.js +137 -0
  46. package/dist/core/pointer.js +29 -0
  47. package/dist/core/result-report.js +302 -0
  48. package/dist/core/risk-callers.js +851 -0
  49. package/dist/core/runner-version.js +45 -0
  50. package/dist/core/secret-path.js +34 -0
  51. package/dist/core/sections.js +230 -0
  52. package/dist/core/state.js +51 -0
  53. package/dist/core/syntax.js +1 -0
  54. package/dist/core/test-commands.js +334 -0
  55. package/dist/core/test-coverage.js +74 -0
  56. package/dist/core/test-discovery.js +1382 -0
  57. package/dist/core/test-evidence.js +527 -0
  58. package/dist/core/test-state.js +81 -0
  59. package/dist/core/truncate.js +12 -0
  60. package/dist/core/units.js +349 -0
  61. package/dist/describe.js +23 -0
  62. package/dist/guide.js +33 -0
  63. package/dist/host.js +24 -0
  64. package/dist/jev/client.js +456 -0
  65. package/dist/jev/pool.js +54 -0
  66. package/dist/jev/types.js +1 -0
  67. package/dist/mcp/main.js +124 -0
  68. package/dist/mcp/protocol.js +210 -0
  69. package/dist/mcp/tools.js +129 -0
  70. package/dist/presets/docs.js +62 -0
  71. package/dist/presets/risk.js +179 -0
  72. package/dist/presets/spec.js +81 -0
  73. package/dist/presets/witnesses.js +249 -0
  74. package/dist/render.js +114 -0
  75. package/dist/report-schema.js +1356 -0
  76. package/dist/result-types.js +1 -0
  77. package/dist/result.js +3 -0
  78. package/dist/runtime.js +1 -0
  79. package/dist/session.js +147 -0
  80. package/dist/texts/ask-files.js +3 -0
  81. package/dist/texts/ask.js +4 -0
  82. package/dist/texts/check-diff.js +20 -0
  83. package/dist/texts/configuration.js +1 -0
  84. package/dist/texts/find.js +19 -0
  85. package/dist/texts/guide.js +3 -0
  86. package/dist/texts/instructions.js +72 -0
  87. package/dist/texts/locate.js +15 -0
  88. package/dist/texts/select-tests.js +4 -0
  89. package/dist/tools/ask-files.js +450 -0
  90. package/dist/tools/ask-schema.js +70 -0
  91. package/dist/tools/ask.js +1147 -0
  92. package/dist/tools/check-diff.js +594 -0
  93. package/dist/tools/docs-check.js +408 -0
  94. package/dist/tools/find.js +682 -0
  95. package/dist/tools/locate.js +602 -0
  96. package/dist/tools/review-report.js +230 -0
  97. package/dist/tools/select-tests.js +821 -0
  98. package/dist/tools/spec-check.js +263 -0
  99. package/docs/adr/0001-strict-typescript-pure-core-offline-tests.md +31 -0
  100. package/docs/adr/0002-one-http-protocol-across-hosts.md +17 -0
  101. package/docs/adr/0003-explicit-scope-conservative-automation.md +19 -0
  102. package/docs/adr/0004-compiled-typed-intents.md +19 -0
  103. package/docs/adr/0005-evidence-construction-before-judgment.md +19 -0
  104. package/docs/adr/0006-visible-uncertainty-constrained-controls.md +21 -0
  105. package/docs/adr/0007-bounded-evidence-visible-limits.md +21 -0
  106. package/docs/adr/0008-static-test-discovery-conservative-plans.md +19 -0
  107. package/docs/adr/0009-session-cache-requested-model-identity.md +17 -0
  108. package/docs/adr/0010-mcp-server-thin-host.md +23 -0
  109. package/docs/agent-instructions.md +120 -0
  110. package/docs/design.md +16 -4
  111. package/docs/mcp.md +233 -0
  112. package/docs/tools/jev_ask.md +8 -5
  113. package/docs/tools/jev_ask_files.md +2 -1
  114. package/docs/tools/jev_check_diff.md +4 -1
  115. package/docs/tools/jev_find_files.md +2 -1
  116. package/docs/tools/jev_locate_in_file.md +5 -0
  117. package/docs/tools/jev_select_tests.md +4 -1
  118. package/package.json +19 -4
  119. package/rules/jev-ask.md +22 -1
  120. package/server.json +57 -0
  121. package/src/adapters/ask-files.ts +11 -3
  122. package/src/adapters/ask-proof.ts +69 -11
  123. package/src/adapters/canonical-path.ts +18 -0
  124. package/src/adapters/command.ts +102 -36
  125. package/src/adapters/docs.ts +33 -14
  126. package/src/adapters/evidence-context.ts +169 -0
  127. package/src/adapters/exec.ts +226 -0
  128. package/src/adapters/files.ts +146 -16
  129. package/src/adapters/find.ts +37 -7
  130. package/src/adapters/git-base.ts +7 -1
  131. package/src/adapters/git.ts +61 -8
  132. package/src/adapters/locate-file.ts +51 -9
  133. package/src/adapters/private-storage.ts +155 -0
  134. package/src/adapters/risk-callers.ts +7 -2
  135. package/src/adapters/shell.ts +113 -0
  136. package/src/adapters/test-inventory.ts +12 -4
  137. package/src/configuration.ts +55 -14
  138. package/src/constants.ts +37 -5
  139. package/src/core/ask-references.ts +262 -146
  140. package/src/core/asks.ts +79 -7
  141. package/src/core/command-output.ts +17 -1
  142. package/src/core/import-boundaries.ts +8 -3
  143. package/src/core/locate.ts +8 -5
  144. package/src/core/output.ts +34 -0
  145. package/src/core/result-report.ts +410 -0
  146. package/src/core/secret-path.ts +37 -0
  147. package/src/core/state.ts +8 -1
  148. package/src/core/units.ts +3 -2
  149. package/src/host.ts +11 -0
  150. package/src/index.ts +3 -0
  151. package/src/jev/client.ts +66 -16
  152. package/src/jev/types.ts +24 -3
  153. package/src/mcp/main.ts +135 -0
  154. package/src/mcp/protocol.ts +332 -0
  155. package/src/mcp/tools.ts +179 -0
  156. package/src/render.ts +109 -0
  157. package/src/report-schema.ts +1380 -0
  158. package/src/result-types.ts +234 -0
  159. package/src/result.ts +4 -1
  160. package/src/runtime.ts +6 -0
  161. package/src/session.ts +59 -0
  162. package/src/setup.ts +13 -5
  163. package/src/texts/ask-files.ts +4 -1
  164. package/src/texts/ask.ts +8 -1
  165. package/src/texts/check-diff.ts +7 -4
  166. package/src/texts/find.ts +8 -2
  167. package/src/texts/guide.ts +8 -16
  168. package/src/texts/instructions.ts +98 -0
  169. package/src/texts/locate.ts +8 -2
  170. package/src/texts/run-end.ts +2 -2
  171. package/src/texts/select-tests.ts +4 -1
  172. package/src/tools/ask-files.ts +311 -18
  173. package/src/tools/ask.ts +722 -95
  174. package/src/tools/check-diff.ts +337 -31
  175. package/src/tools/docs-check.ts +241 -38
  176. package/src/tools/find.ts +389 -29
  177. package/src/tools/locate.ts +387 -25
  178. package/src/tools/review-report.ts +308 -0
  179. package/src/tools/select-tests.ts +484 -23
  180. package/src/tools/spec-check.ts +194 -19
package/CHANGELOG.md CHANGED
@@ -9,6 +9,109 @@ modules are not a stable library API.
9
9
 
10
10
  ## [Unreleased]
11
11
 
12
+ ## [0.3.0] - 2026-10-05
13
+
14
+ ### Breaking
15
+
16
+ - `JEV_TOOLS_URL` (and saved or flag URLs) with plain `http:` is refused unless the host is `127.0.0.1`, `::1` or `localhost`; use `https:`. The configuration error shows neither the URL nor the key and occurs before any request.
17
+ - Files whose base name matches `.env`, `.env.*`, `*.pem`, `id_rsa*`, `*.p12`, `credentials*` or `secrets*` (any depth, case-insensitive; `.env.example`, `.env.sample` and `.env.template` excepted) are refused before reading on every evidence path, including diff units, test inventory, find, locate, ask-files and the pi/omp documentation hook. Each refusal is a named exclusion with the new cause `secret_pattern`; a question that explicitly requires such a file stays unjudged. There is no override.
18
+
19
+ ### Security
20
+
21
+ - `jev_ask` commands and the Windows PowerShell ACL helper no longer inherit `JEV_TOOLS_API_KEY`. The configured key value (environment or saved configuration) is replaced with `[redacted]` in command output before state assembly, including a key prefix left where a long output line is cut, and the number of replacements is reported as a limitation.
22
+
23
+ ### Added
24
+
25
+ - Optional `root` on all six tools, limited to the initial repository's exact Git root or registered live worktrees with the same common directory; invalid overrides refuse before evidence, commands, cache or judgments.
26
+ - Versioned typed reports for every tool outcome, including refused and unjudged work: evidence context, item provenance, scoped diagnostics/actions and separate requested-result, HTTP, cache, control, passage and cost accounting.
27
+ - MCP output schema and structured results from protocol 2025-06-18 onward, with self-contained text for older clients and per-request version isolation.
28
+
29
+ ### Changed
30
+
31
+ - Explicit evidence selectors, rather than ordinary lexical mentions, govern missing-evidence exclusions. Canonical file versions are serialized once with alias metadata; before/current evidence remains distinct and missing requirements affect their own question group unless global.
32
+ - Host guidance now makes Jev discretionary, shares versioned canonical fragments across pi/omp/MCP, and reports current conclusions with evidence provenance and material reservations. The pi/omp opt-out documentation hook remains; MCP requires no manual replacement call.
33
+ - Human output is a projection of the typed report. Static/fallback selection and unavailable judgments never acquire fabricated probabilities; cached results are distinct from fresh requests and unknown cost is not zero.
34
+
35
+ ### Fixed
36
+
37
+ - Historical-only and deleted-file evidence resolution, supplied-file basename precedence and canonical file-count admission without duplicated alias content.
38
+ - Command output reaches bounded passage selection before immutable-evidence budget refusal, including base snapshots and import closure; reports preserve actual command execution/cwd even when later collection fails.
39
+ - Selection reports distinguish unmatched candidate criteria, partial matches, excluded inventory and named conservative-widening triggers from absence of affected tests.
40
+ - Review reports retain documentation completeness/collection reservations and risk/coverage witness diagnostics. Residual absence summaries remain derived observations within the considered inventory, not extra judgments or global coverage claims.
41
+ - Recovery actions preserve the actual evidence/control limitation instructions rather than generic repetition advice.
42
+ - Local-caller reports preserve their independent unsure/abstain bands and matching probabilities; specification drift remains one pointer decision rather than duplicated judgments for every candidate unit.
43
+ - MCP malformed tool arguments remain JSON-RPC invalid-parameter errors, separate from well-formed calls refused by evidence admission.
44
+ - Every judgment stage binds cache identity and serialized admission to its admitted root/base context, including auxiliary command passages. Locate planning reserves that metadata capacity before allocating evidence.
45
+ - Historical selectors use protected base reads for ignored paths, symlinks, non-text content and deleted files; current/base versions share the distinct-file ceiling without bypassing rejected admissions.
46
+
47
+ ## [0.2.0] - 2026-10-03
48
+
49
+ ### Added
50
+
51
+ - `jev-agent-tools-mcp`: a dependency-free MCP stdio server exposing the same six
52
+ tools to any MCP client. It reuses the existing tool factories, session limits,
53
+ HTTP client and saved configuration; the binary ships as compiled JavaScript built
54
+ by `npm run build`.
55
+ - MCP setup guide (`docs/mcp.md`) and a project instruction template for MCP agents
56
+ (`docs/agent-instructions.md`, for `CLAUDE.md`, `AGENTS.md` or Kiro steering).
57
+ - `JEV_TOOLS_BASH` and `JEV_TOOLS_ROOT` settings (Windows bash path; MCP root).
58
+ - MCP Registry publication: `server.json` (`io.github.NomenAK/jev-agent-tools`) and
59
+ `mcpName` in `package.json`. After the npm publish, the release workflow waits for the
60
+ approved version and its `mcpName` on npm, then publishes with a pinned, checksum-verified
61
+ `mcp-publisher` over GitHub OIDC; an existing registry version is skipped only
62
+ when its server definition matches the approved tarball's metadata.
63
+ - `scripts/check-mcp-package.ts`: CI and release gate that installs the packed
64
+ tarball, checks modern discovery and all advertised legacy handshakes, and
65
+ exercises `jev_ask` against a local synthetic HTTP endpoint.
66
+ - Native Windows and macOS CI for MCP, managed process termination, private
67
+ configuration, platform paths and the installed package; Linux retains the
68
+ complete offline suite.
69
+
70
+ ### Changed
71
+
72
+ - The npm package now includes `SECURITY.md` and `docs/adr/`, which shipped
73
+ documentation already linked to.
74
+
75
+ ### Fixed
76
+
77
+ - MCP command cancellation and timeout now finish process-group escalation even
78
+ when the parent shell exits first. Closing stdin, SIGTERM and SIGINT drain
79
+ outstanding tool calls before the server exits; cancelled calls stay silent.
80
+ - Windows command cleanup maps MSYS descendants before forced termination, so
81
+ Git Bash fork/exec no longer hides ordinary descendants from `taskkill /T`.
82
+ - Package checks use local archive paths on Windows and macOS; private-storage
83
+ test fixtures use canonical macOS temporary paths without relaxing symlink checks.
84
+ - Modern MCP discovery now includes server identity in result metadata, and
85
+ tool lists declare immediately stale, private caching as required by the
86
+ 2026-07-28 protocol.
87
+ - MCP Registry reruns skip only an identical server definition. Divergent,
88
+ malformed or inconclusive responses fail; registry metadata is checked
89
+ against `server.json` inside the approved tarball before lookup.
90
+
91
+ - In omp, first-launch Jev setup no longer waits for credential entry inside the
92
+ bounded `session_start` handler. The offer and input dialogs stay open while
93
+ users find their endpoint and key, rather than closing after the host's
94
+ 30-second event deadline.
95
+ - `JEV_TOOLS_MAX_USD` could be overshot by up to seven requests: concurrent batches
96
+ were all admitted before any cost was reported. Under a USD limit, requests are
97
+ now admitted one at a time, so only the final admitted request can exceed it.
98
+ - Windows: `jev_ask` commands ran `env CI=1 bash`, which fails without `env` and
99
+ resolves to the WSL launcher. Git for Windows bash is now used.
100
+ - Windows: imported providers were never found for `jev_check_diff` risk callers
101
+ because a repository path was resolved with platform path semantics.
102
+ - Windows: node:test `file:///C:/...` failure locations (including `%20`) were not
103
+ mapped back to repository files.
104
+ - Windows: an 8.3 short working directory (for example `C:\Users\NAME~1`) did not
105
+ relate to the Git root, which emptied import closures and file references.
106
+ - Line endings are pinned to LF via `.gitattributes`, so lint and the rule/guideline
107
+ parity check pass on Windows checkouts with `core.autocrlf=true`.
108
+ - Windows: saving or loading `/jev-setup` configuration always failed, because the
109
+ privacy check read POSIX mode bits, which Windows reports as `0o666` for every file.
110
+ Windows now checks the folder and file access lists (allow entries limited to the
111
+ current user, SYSTEM and Administrators) and restricts a new folder when saving.
112
+ - Tests: `secret-input` passed a `C:\` path to `import()`; the risk-caller latency
113
+ test compared one run with a fixed 250 ms and now checks 250- to 1000-line scaling.
114
+
12
115
  ## [0.1.4] - 2026-10-02
13
116
 
14
117
  ### Added
@@ -74,7 +177,9 @@ Tagged but never published to npm: the unscoped package name was rejected.
74
177
 
75
178
  Tagged but never published to npm: the publish workflow failed before upload.
76
179
 
77
- [Unreleased]: https://github.com/NomenAK/jev-tools/compare/v0.1.4...HEAD
180
+ [Unreleased]: https://github.com/NomenAK/jev-tools/compare/v0.3.0...HEAD
181
+ [0.3.0]: https://github.com/NomenAK/jev-tools/compare/v0.2.0...v0.3.0
182
+ [0.2.0]: https://github.com/NomenAK/jev-tools/compare/v0.1.4...v0.2.0
78
183
  [0.1.4]: https://github.com/NomenAK/jev-tools/compare/v0.1.3...v0.1.4
79
184
  [0.1.3]: https://github.com/NomenAK/jev-tools/compare/v0.1.0...v0.1.3
80
185
  [0.1.2]: https://github.com/NomenAK/jev-tools/tree/v0.1.2
@@ -0,0 +1,43 @@
1
+ # Contributing
2
+
3
+ Issues and external pull requests are welcome. Use English for issues, pull requests, documentation, comments, and test descriptions; keep non-English fixtures when they test language or encoding behavior. For vulnerabilities, follow [SECURITY.md](SECURITY.md).
4
+
5
+ ## Issues or pull requests?
6
+
7
+ Open an issue for a reproducible product bug or a feature request. Include the package and host versions, expected and actual behavior, and a minimal sanitized reproduction. Small, focused fixes or documentation corrections can go straight to a pull request. Discuss new tools, contract changes, and research-dependent features in an issue before implementing them.
8
+
9
+ An issue may describe an unmet need without claiming that a method already works. Features such as co-change suggestions are not accepted for implementation without a new, validated method. Propose the method, its evaluation protocol, and reproducible evidence in an issue first; an unvalidated heuristic or a renamed version of it is not enough.
10
+
11
+ ## Local checks
12
+
13
+ Use Node.js 24 or newer and npm. From a checkout, with development dependencies enabled:
14
+
15
+ ```sh
16
+ npm ci --include=optional
17
+ npm run typecheck
18
+ npm run build
19
+ npm run check:imports
20
+ npm run lint
21
+ node scripts/generate-instructions.ts --check
22
+ npm test
23
+ ```
24
+
25
+ `npm run build` compiles only the MCP server into `dist/` (git-ignored); `npm pack` runs it automatically. To try the server against a checkout, see [From a clone](docs/mcp.md#from-a-clone). CI packs the package and runs `node scripts/check-mcp-package.ts <tarball>`: it installs the tarball into an empty directory, checks modern discovery and all advertised legacy handshakes, lists the six tools with their schemas and caching fields, and runs `jev_ask` through a local synthetic HTTP endpoint. This verifies installed integration, not live model accuracy. Linux runs the full offline suite; native Windows and macOS jobs run targeted MCP, process, configuration and packaging checks.
26
+
27
+ Agent policy and result-reading guidance are versioned in `src/texts/instructions.ts`. After changing them, run `node scripts/generate-instructions.ts` to update the checked-in omp rule and MCP project block; `--check` verifies that those copies remain synchronized. Keep host differences explicit rather than maintaining independent policy text.
28
+
29
+ ## Releases
30
+
31
+ Maintainers release by pushing a `vX.Y.Z` tag on reviewed `main`. Before tagging, set the same version in `package.json`, in both `version` fields of `server.json`, and in a `CHANGELOG.md` section; `test/server-json.test.ts` fails if they drift. [`publish.yml`](.github/workflows/publish.yml) then packs once, checks the packed MCP server, publishes the approved tarball to npm with trusted publishing, publishes `server.json` to the MCP Registry with GitHub OIDC, and creates a draft GitHub Release. Each publication step skips a version that already exists with the same content and fails on anything inconclusive.
32
+
33
+ Keep optional native dependencies enabled for development. These checks make no Jev API calls and need no Jev key. Dependency installation may use the network. Some runner-identity tests skip when additional runners are unavailable locally; CI provisions those runners in [.github/workflows/ci.yml](.github/workflows/ci.yml).
34
+
35
+ Maintainers run a private regression probe on reviewed release candidates before release and on the published package before announcing it. Contributors do not need access to that probe or its credentials.
36
+
37
+ ## Pull request expectations
38
+
39
+ Keep changes focused. Explain the user-visible behavior, link the relevant issue when there is one, and report the checks you actually ran, including skips or limitations. Add or update deterministic tests for changed behavior and regressions, and update affected documentation. Public CI must pass without service credentials.
40
+
41
+ Do not make accuracy, recall, speed, or other measurement claims without describing the method, baseline, data, and limitations sufficiently to reproduce and review them. Do not include credentials, raw service responses, private data, or personal configuration in issues, patches, or logs. Use synthetic or sanitized examples.
42
+
43
+ Check the name and email attached to your commits before submitting; GitHub's noreply email is an option if you do not want to publish a personal email address.
package/README.md CHANGED
@@ -1,28 +1,55 @@
1
1
  # jev-agent-tools
2
2
 
3
- Six evidence-oriented tools for pi and omp, compatible with the Jev API format. Use them to navigate unfamiliar code, ask typed questions about repository evidence, review completed changes and select existing tests. They complement reading, searching and execution; they do not replace them.
3
+ Six evidence-oriented tools for pi, omp and any MCP client, compatible with the Jev API format. Use them to navigate unfamiliar code, ask typed questions about repository evidence, review completed changes and select existing tests. They complement reading, searching and execution; they do not replace them.
4
+
5
+ [![jev-agent-tools launch video: six tools, one habit, show the evidence. Click to play (74 s).](docs/media/jev-agent-tools-launch.jpg)](docs/media/jev-agent-tools-launch.mp4)
6
+
7
+ [Watch the launch video](docs/media/jev-agent-tools-launch.mp4) (74 s, MP4).
4
8
 
5
9
  ## Install
6
10
 
7
- Install through your host's package manager. The npm package is `jev-agent-tools`. It ships TypeScript sources; no separate compilation is required.
11
+ Install through your host's package manager, or register the MCP server with an MCP client. The npm package is `jev-agent-tools`. pi and omp load its TypeScript sources directly; the MCP server ships prebuilt.
8
12
 
9
13
  ### pi
10
14
 
11
15
  ```sh
12
- pi install npm:jev-agent-tools@0.1.4
16
+ pi install npm:jev-agent-tools@0.3.0
13
17
  # Project-local installation:
14
- pi install -l npm:jev-agent-tools@0.1.4
18
+ pi install -l npm:jev-agent-tools@0.3.0
15
19
  ```
16
20
 
17
21
  ### omp
18
22
 
19
23
  ```sh
20
- omp plugin install jev-agent-tools@0.1.4
24
+ omp plugin install jev-agent-tools@0.3.0
25
+ ```
26
+
27
+ ### Any MCP client
28
+
29
+ Since version 0.2.0, the package also ships `jev-agent-tools-mcp`, a stdio MCP server that exposes the same six tools to any MCP client: Claude Code, Claude Desktop, Kiro, Cursor, VS Code, Codex CLI and others. A typical `mcpServers` entry:
30
+
31
+ ```json
32
+ {
33
+ "mcpServers": {
34
+ "jev": {
35
+ "command": "npx",
36
+ "args": ["-y", "-p", "jev-agent-tools", "jev-agent-tools-mcp", "--root", "/path/to/repository"],
37
+ "env": {
38
+ "JEV_TOOLS_URL": "${JEV_TOOLS_URL}",
39
+ "JEV_TOOLS_API_KEY": "${JEV_TOOLS_API_KEY}"
40
+ }
41
+ }
42
+ }
43
+ }
21
44
  ```
22
45
 
46
+ On Windows most clients start commands without a shell, so use `"command": "cmd"` with `"/c", "npx"` at the start of `args`. The [MCP setup guide](docs/mcp.md) has per-client files, CLI commands, variable interpolation, verification and troubleshooting. Releases are also listed in the official MCP Registry as `io.github.NomenAK/jev-agent-tools`. Add the [agent instructions](docs/agent-instructions.md) to `CLAUDE.md`, `AGENTS.md` or a Kiro steering file so the agent uses and reads the tools correctly.
47
+
48
+ The server reads the same environment variables as pi and omp and the configuration saved by `/jev-setup`. One server process is one session. MCP has no automatic run-end documentation hook; its absence does not require manual replacement calls. `jev_ask` is marked as not read-only while commands are enabled; set `JEV_TOOLS_ALLOW_COMMAND=0` to remove `command` from its schema.
49
+
23
50
  ### Requirements and compatibility
24
51
 
25
- Requires Node.js 24 or later. Supported host baselines are pi 0.87.1 and omp 18.4.10. These are support baselines, not claims that every later version has been individually validated. omp uses its Bun runtime; Node.js is also required for Node-based project checks. Git and, for optional command evidence, Bash must be available. Optional native parsers and file-search acceleration may be unavailable on some platforms; affected tools report their limitations.
52
+ Requires Node.js 24 or later. Supported host baselines are pi 0.87.1 and omp 18.4.10. These are support baselines, not claims that every later version has been individually validated. omp uses its Bun runtime; Node.js is also required for Node-based project checks. Git and, for optional command evidence, Bash must be available. On Windows, command evidence uses Git for Windows bash (found next to `git` on `PATH` or under Program Files); the WSL `bash.exe` launchers are never used. Set `JEV_TOOLS_BASH` to the full path of another bash. Optional native parsers and file-search acceleration may be unavailable on some platforms; affected tools report their limitations.
26
53
 
27
54
  The published `jev-agent-tools@0.1.3` package was also checked with **pi 1.0.0** on Linux under Node.js 24.15.0: npm installation, TypeScript checking against the host types, all six tools in the actual CLI, and reading-guide injection passed. The CLI smoke used a simulated conversation provider and Jev endpoint; it verifies host integration, not live model accuracy or every tool scenario.
28
55
 
@@ -42,9 +69,11 @@ In the main interactive terminal of pi or omp, a first launch without configurat
42
69
 
43
70
  No dialog appears in print, JSON or RPC modes, or in sub-agents; configure those with the environment variables below. Changes apply immediately, without restarting the host.
44
71
 
72
+ Interactive setup waits for submission or cancellation, without a credential-entry timeout. The first-launch offer does not keep the host's startup event handler open while you find the endpoint or key.
73
+
45
74
  **Precedence per field:** environment variable, then launch flag, then this session's setup, then saved configuration, then the default model `openjev`. A field set by the environment or a flag is shown as controlled and is never saved.
46
75
 
47
- **Saved configuration** lives outside the repository at `$XDG_CONFIG_HOME/jev-agent-tools/config.json` (default `~/.config/jev-agent-tools/config.json`), in a private directory (`0700`) with a private file (`0600`). **The key is stored in plaintext, not encrypted.** Storage that is a symlink, group/world-accessible, not owned by you or malformed is refused rather than overwritten.
76
+ **Saved configuration** lives outside the repository at `$XDG_CONFIG_HOME/jev-agent-tools/config.json` (default `~/.config/jev-agent-tools/config.json`), in a private directory (`0700`) with a private file (`0600`). On Windows, where mode bits do not exist, privacy is the folder's access list: saving restricts it to you, SYSTEM and Administrators, and loading refuses any other account with access. **The key is stored in plaintext, not encrypted.** Storage that is a symlink, accessible to other users, not owned by you or malformed is refused rather than overwritten. The MCP server also reads this file, after environment variables.
48
77
 
49
78
  ### Environment variables
50
79
 
@@ -61,13 +90,15 @@ export JEV_TOOLS_MODEL="openjev"
61
90
 
62
91
  | Variable | Meaning |
63
92
  |---|---|
64
- | `JEV_TOOLS_URL` | Required complete endpoint URL compatible with the Jev API format. |
65
- | `JEV_TOOLS_API_KEY` | Required Bearer credential; configuration values are not printed in tool output. |
93
+ | `JEV_TOOLS_URL` | Required complete endpoint URL compatible with the Jev API format. Must be `https:`; plain `http:` is accepted only for `127.0.0.1`, `::1` or `localhost`. |
94
+ | `JEV_TOOLS_API_KEY` | Required Bearer credential; configuration values are not printed in tool output, and command children never receive it. |
66
95
  | `JEV_TOOLS_MODEL` | Requested model string, default `openjev`; a moving alias, not a guarantee of served-model identity. |
67
96
  | `JEV_TOOLS_MAX_CALLS` | Session-wide non-negative safe-integer call limit; absent or empty means unlimited. Invalid values refuse requests. |
68
97
  | `JEV_TOOLS_MAX_USD` | Session-wide finite non-negative cost limit, including fractions; absent or empty means unlimited. Invalid values refuse requests. |
69
98
  | `JEV_TOOLS_ALLOW_COMMAND` | `0` disables `command` in `jev_ask`; otherwise commands run with ordinary shell permissions, without an additional sandbox. |
70
99
  | `JEV_TOOLS_AUTO_DOCS` | `0` disables the automatic run-end documentation check. |
100
+ | `JEV_TOOLS_BASH` | Optional full path of the bash used for `jev_ask` commands on Windows. |
101
+ | `JEV_TOOLS_ROOT` | MCP server only: repository directory when `--root` is not given. |
71
102
 
72
103
  Without the endpoint or key, tools remain registered and explain the missing configuration; the automatic documentation check is disabled. There is no fallback to a chat model. Per-tool `max_calls` is separate from session limits. A model name echoed by the response does not establish which model was actually served.
73
104
 
@@ -84,39 +115,49 @@ Without the endpoint or key, tools remain registered and explain the missing con
84
115
 
85
116
  Use native read/search tools or code for exact source text, known symbols, filenames, line numbers, counts and arithmetic. Run commands yourself when you need their full output. Tool reference examples use fictional repository paths and are illustrative calls, not recorded executions.
86
117
 
118
+ ### Evidence root
119
+
120
+ All six tools accept optional `root: string`. Without it, the host's current directory or configured MCP server directory retains its existing behavior. An override must name exactly the initial repository's Git top-level or a registered live worktree with the same canonical Git common directory. Relative overrides resolve against the initial directory; absolute paths are accepted only for this parameter. Subdirectories, other clones/repositories, parent traversal and symlink components are refused before evidence collection, command execution, cache access or judgment. There is no fallback to a different checkout.
121
+
122
+ The admitted root governs files, base/diff, inventories, specification paths, runner plans and command cwd for that call only. It does not change another call or the automatic documentation hook. File arguments remain repository-relative and confined. A command still has ordinary shell permissions, not a sandbox. Check the reported authority, requested/effective root and resolved base before using a result.
123
+
87
124
  ## Read the results
88
125
 
89
- A line without a mark is a **verdict**: a lead to check before editing, deleting or reporting completion, not a proof. Probabilities concern the evidence shown, not everything in your repository.
126
+ Each result begins with execution state: **complete**, **partial**, **not_judged** or **refused**. This describes processing, not correctness, safety or coverage. Items distinguish fresh or cached Jev judgments, static treatment and work never judged. Static selection and conservative fallback carry no invented probability. A judged line without an uncertainty mark is a **verdict**: a lead to check, not proof beyond the supplied evidence.
90
127
 
91
128
  | Mark | Meaning and next action |
92
129
  |---|---|
93
130
  | `unsure` | The answer is ambiguous or a control failed. Read the indicated passage or add the specific evidence that would settle it. Do not merely reword the question. |
94
- | `abstain` | A necessary piece is missing. Add the named file or command evidence and ask once. |
131
+ | `abstain` | A necessary piece is missing. Obtain the named evidence or leave the conclusion open; another Jev call is optional when the changed evidence makes it useful. |
95
132
  | `no (not shown)` / `not addressed` | The supplied evidence does not show the statement; that does not make it false. |
96
133
  | `uncalibrated` | No established error-rate calibration applies to this ask; treat it as a hint even if its probability is high. |
97
- | Bracketed lines | Collection, parsing, budget or display limitations, with the next manual action. |
134
+ | Diagnostics and next actions | Typed cause, origin, affected scope, materiality and recovery instructions; distinguish uncertain judgments from work never judged. |
98
135
 
99
136
  Ordinary boolean verdict bands are at or below 0.20 and at or above 0.80; category/level verdicts require a leading-option probability of at least 0.85 after applicable controls. Fixed checks and navigation tools have their own thresholds, described in their references and [design](docs/design.md).
100
137
 
101
- The footer reports **calls · questions · cost · cache · time**: request count, questions judged, reported USD cost, cache hits/requests and elapsed time. A tool invocation may require several requests for batching or controls. Missing cost reporting is not evidence of a free request.
138
+ Accounting separates **HTTP attempts**, **questions sent**, **requested results** (fresh/cache/static/not judged), **cache probes**, auxiliary controls and passage selection, current reported USD cost and elapsed time. These counts are not interchangeable. A cached judgment can have zero HTTP attempts; zero attempts can also mean static work or no judgment. Unknown cost is unreported, not free. Context values distinguish known, unknown, not collected and not applicable.
139
+
140
+ pi and omp expose the versioned report as `details.result`. MCP versions from 2025-06-18 expose the same report under `structuredContent.result` with an advertised output schema; older versions receive self-contained text from the same report. Text preserves material limitations, evidence provenance and useful read/runner commands.
102
141
 
103
- In a final report, explicitly identify conclusions marked `unsure` or `abstain` as unconfirmed by Jev. If subsequent reading settles them, distinguish that verification from the tool's result and cite the decisive evidence. Otherwise retain the uncertainty in your summary and recommendation.
142
+ Report current conclusions, decisive evidence with origin and scope, and material reservations. If native reading or execution settles an earlier `unsure` or `abstain` on the same context, attribute the current conclusion to that native evidence, not Jev. If uncertainty returned by Jev remains material, explicitly say Jev did not confirm the conclusion and name the missing evidence and impact. Independent limits, stale evidence and conflicting contexts remain visible. Reported checks are not observed execution; no exhaustive history block or new persistent register is required.
104
143
 
105
144
  ## Usage guidance for pi and omp
106
145
 
107
146
  The extension supplies the shared reading guide in both hosts. omp discovers enabled npm plugin rules during normal startup; pi does not automatically discover the package's `rules/` directory. In pi, the same decision policy is part of the `jev_ask` tool guidelines, so it is present whenever `jev_ask` is active. A forced opaque prompt override may bypass this integration; disabled tools or disabled omp rules are not covered. This README block is recommended usage guidance, not itself an installed instruction:
108
147
 
109
- > Before concluding that a failure is a code bug, an incorrect test or an environment problem, or that a plan matches documentation, pass the relevant files to [jev_ask](docs/tools/jev_ask.md) and weigh its answer against your own reading. Include both the failing test and the code it exercises; identify any conclusion that remains unconfirmed.
148
+ > Use Jev for a bounded semantic judgment when it can change an open decision or focus inspection. Use decisive native reading, search or authorized execution directly. A Jev call is not a prerequisite for a conclusion, review or completion. When choosing a call, supply both sides of a comparison and the evidence that distinguishes explanations. Revisit only when changed evidence, context or a useful new question warrants it; repeating unchanged evidence is not a recovery action.
149
+
150
+ MCP clients receive the guide as server `instructions`, which some clients ignore. Add the [agent instructions](docs/agent-instructions.md) to the project's `CLAUDE.md`, `AGENTS.md` or Kiro steering file.
110
151
 
111
152
  ## Data and command safety
112
153
 
113
154
  Repository evidence, notes and optional command output are sent to your configured endpoint. Review its data-handling policy before using confidential repositories. See [security guidance](SECURITY.md).
114
155
 
115
- File collection is confined to the repository: absolute paths, parent traversal, escaping symlinks, Git metadata and internal URLs are not file inputs. Build output, binaries, lockfiles and oversized files are skipped or refused with visible limits; evidence is not silently truncated into a verdict. This confinement does **not** sandbox a command. `jev_ask` commands can read, write or access the network with the host's shell permissions. omp uses execution approval for commands; pi does not supply an additional per-tool command approval. Set `JEV_TOOLS_ALLOW_COMMAND=0` to disable them.
156
+ File collection is confined to the repository: absolute paths, parent traversal, escaping symlinks, Git metadata and internal URLs are not file inputs. Files named like secrets (`.env`, `.env.*` except `.env.example`/`.env.sample`/`.env.template`, `*.pem`, `id_rsa*`, `*.p12`, `credentials*`, `secrets*`, any depth, any case) are refused before reading and named with cause `secret_pattern`. Build output, binaries, lockfiles and oversized files are skipped or refused with visible limits; evidence is not silently truncated into a verdict. This confinement does **not** sandbox a command. `jev_ask` commands can read, write or access the network with the host's shell permissions; they run without `JEV_TOOLS_API_KEY`, and the configured key is replaced with `[redacted]` in their output. omp uses execution approval for commands; pi does not supply an additional per-tool command approval; MCP clients apply their own tool approval, and the server marks `jev_ask` as not read-only. Set `JEV_TOOLS_ALLOW_COMMAND=0` to disable them.
116
157
 
117
158
  ## Automatic documentation check
118
159
 
119
- On a dirty tree, the extension can check existing Markdown documentation once at run end against changes from `HEAD`, including untracked files. A flagged existing sentence can request one additional turn to update it or explain why it remains correct. Merely unsure sections do not trigger another turn. Missing configuration, disabled automation, invalid/exhausted session budgets or a clean tree skip the check. Errors and timeout do not block the host. This is not a check for every missing documentation obligation.
160
+ On a dirty tree, the extension can check existing Markdown documentation once at run end against changes from `HEAD`, including admitted untracked files (not gitignored, not secret-named), which are sent to the endpoint without an explicit tool call. A flagged existing sentence can request one additional turn to inspect and update it or explain with evidence why it remains correct; a flag does not itself establish falsehood or require a second call. Merely unsure sections do not trigger another turn. `JEV_TOOLS_AUTO_DOCS=0`, missing configuration, invalid/exhausted session budgets or a clean tree skip the check. Errors and timeout do not block the host. This opt-out host feature does not certify documentation completeness. MCP has no hook and requires no manual replacement ritual.
120
161
 
121
162
  ## Known limits
122
163
 
package/SECURITY.md ADDED
@@ -0,0 +1,43 @@
1
+ # Security policy
2
+
3
+ ## Supported versions
4
+
5
+ Security fixes target the latest patch release in the 0.1.x series. Older 0.1.x patches should be upgraded; 0.0.x and unreleased snapshots are not supported releases.
6
+
7
+ ## Report privately
8
+
9
+ Use GitHub's [Report a vulnerability](https://github.com/NomenAK/jev-tools/security/advisories/new) form. Do not disclose vulnerabilities in public issues or pull requests. If the form is unavailable, open an issue asking to restore private reporting, without vulnerability details. There is no email reporting channel.
10
+
11
+ Include the affected version, impact, and a minimal reproduction using synthetic data. Never include live credentials, private repository contents, or personal configuration. If a credential may have been exposed, revoke or rotate it independently of this report.
12
+
13
+ This is a solo-maintained project. Reports are reviewed on a best-effort basis; there is no guaranteed acknowledgement or fix deadline. Follow-up and disclosure coordination take place in the private report. Please coordinate public disclosure there.
14
+
15
+ ## Scope and trust boundaries
16
+
17
+ Report repository-confinement escapes in file evidence collection, including reads outside the selected repository; unintended secret exposure caused by jev-tools; and unintended command execution or bypasses of disabled command execution.
18
+
19
+ File evidence collection is confined to the repository, but optional commands are not sandboxed: they run with the host's permissions and may read or modify files or access the network. `JEV_TOOLS_ALLOW_COMMAND=0` disables this command path. Selected repository evidence and requested command output are sent to the configured API endpoint. Review the data and endpoint before use.
20
+
21
+ ### Secret-named files are refused
22
+
23
+ Every evidence admission path (`jev_ask` paths and import closure, `jev_ask_files`, `jev_find_files`, `jev_locate_in_file`, `jev_check_diff` diff units and local callers, `jev_select_tests` inventory and the automatic pi/omp documentation check) refuses a file whose base name matches `.env`, `.env.*`, `*.pem`, `id_rsa*`, `*.p12`, `credentials*` or `secrets*`, at any depth and case-insensitively, whatever its Git status (tracked, untracked or added). `.env.example`, `.env.sample` and `.env.template` remain admitted. The refusal happens before the content is read: the result names the path with cause `secret_pattern`, and a question that explicitly requires that file stays unjudged. There is no per-call or environment override. Files with other names are not inspected for secrets.
24
+
25
+ ### Commands never receive the API key
26
+
27
+ `jev_ask` commands and the Windows PowerShell ACL helper run with the host environment minus `JEV_TOOLS_API_KEY`. Before command output enters a state, every occurrence of the configured key value, whether it came from the environment or the saved configuration, is replaced with `[redacted]` in stdout, stderr and the echoed command line; the result reports how many replacements were made. Detection of other secrets in command output is not promised.
28
+
29
+ ### The key travels only over HTTPS or loopback
30
+
31
+ `JEV_TOOLS_URL` must use `https:`. Plain `http:` is accepted only for `127.0.0.1`, `::1` or `localhost`; any other `http:` URL is a configuration error, reported without the URL or key and before any request, so the Bearer key is never sent in clear text over a network.
32
+
33
+ ### Automatic documentation check
34
+
35
+ On pi and omp, the run-end documentation check (disable with `JEV_TOOLS_AUTO_DOCS=0`) sends changed units from a dirty tree to the endpoint without an explicit tool call, including admitted untracked files that are not gitignored. Secret-named files are refused as above; anything else untracked and not ignored can be sent. Keep sensitive scratch files gitignored or outside the repository.
36
+
37
+ Saved interactive configuration stores the API key in plaintext in a private user-level file (`~/.config/jev-agent-tools/config.json` by default). Privacy uses each operating system's own model: owner-only mode bits on POSIX; on Windows, an access list whose allow entries are only the current user, SYSTEM and Administrators, read by SID through the system Windows PowerShell. Protect the account and back-ups accordingly, or use environment variables from a secret manager instead.
38
+
39
+ The MCP server (`jev-agent-tools-mcp`) has the same boundaries. It talks to its client only over stdio and opens no network listener. MCP client configuration files that contain a literal API key are as sensitive as the saved configuration; prefer the client's environment-variable interpolation and do not commit such files. Tool approval is the MCP client's responsibility; the server marks `jev_ask` as not read-only while commands are enabled.
40
+
41
+ Command cancellation and timeout, and MCP connection shutdown, complete bounded termination of the managed process group on POSIX or await the system process-tree termination operation on Windows. This is cleanup, not containment: deliberately detached descendants or processes that escape that tree are not tracked, and previously completed side effects are not undone.
42
+
43
+ Expected execution of an explicitly supplied command, intentional submission of evidence, inaccurate judgments, and ordinary bugs or feature requests are not by themselves security vulnerabilities. Report ordinary product problems through issues; report host or API-service vulnerabilities to their respective maintainers. If unsure about a jev-tools security impact, use the private form.
@@ -0,0 +1,75 @@
1
+ import { createHash } from "node:crypto";
2
+ import { tokenize, } from "../core/lexical.js";
3
+ import { loadSyntaxRootParser } from "./syntax.js";
4
+ /** Owns one invocation's source versions; never retains repository data across calls. */
5
+ export async function createAnalysisContext(counter, sourceParser) {
6
+ const fingerprints = new Map();
7
+ const fingerprint = (text) => {
8
+ let value = fingerprints.get(text);
9
+ if (value === undefined) {
10
+ value = createHash("sha256").update(text).digest("hex");
11
+ fingerprints.set(text, value);
12
+ }
13
+ return value;
14
+ };
15
+ const lexical = new Map();
16
+ const tokenizeSource = (path, text, python = false) => {
17
+ const version = fingerprint(text);
18
+ let versions = lexical.get(path);
19
+ if (!versions) {
20
+ versions = new Map();
21
+ lexical.set(path, versions);
22
+ }
23
+ const key = `${version}:${python}`;
24
+ let tokens = versions.get(key);
25
+ if (!tokens) {
26
+ counter?.tokenized(path, version);
27
+ tokens = tokenize(text, python);
28
+ versions.set(key, tokens);
29
+ }
30
+ return tokens;
31
+ };
32
+ const source = sourceParser ?? (await loadSyntaxRootParser());
33
+ if (!source)
34
+ return {
35
+ parser: undefined,
36
+ fingerprint,
37
+ counter,
38
+ tokenize: tokenizeSource,
39
+ };
40
+ const roots = new Map();
41
+ const parser = {
42
+ supports: source.supports,
43
+ parseRaw(path, text) {
44
+ const version = fingerprint(text);
45
+ let versions = roots.get(path);
46
+ if (!versions) {
47
+ versions = new Map();
48
+ roots.set(path, versions);
49
+ }
50
+ let parsed = versions.get(version);
51
+ if (!parsed) {
52
+ counter?.parsed(path, version);
53
+ parsed = source.parseRaw(path, text);
54
+ versions.set(version, parsed);
55
+ }
56
+ return parsed;
57
+ },
58
+ parse(path, text) {
59
+ const parsed = this.parseRaw(path, text);
60
+ if (!parsed.ok)
61
+ return parsed;
62
+ return parsed.root.find({ rule: { kind: "ERROR" } })
63
+ ? { ok: false, error: "Source syntax incomplete" }
64
+ : parsed;
65
+ },
66
+ declarations: source.declarations,
67
+ };
68
+ return {
69
+ parser,
70
+ fingerprint,
71
+ counter,
72
+ tokenize: tokenizeSource,
73
+ resolved: (path, text) => counter?.resolved(path, fingerprint(text)),
74
+ };
75
+ }