evals 2.10.0 → 2.11.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
@@ -48,7 +48,7 @@ The agent runs with its **normal permission model** — `evals` never passes ski
48
48
  |----------|-----------|--------|
49
49
  | `ARIZE_AGENT=<id>` | `start.sh` / `start.ps1` | Skip the picker and use this agent (`claude`, `codex`, `cursor-agent`, `copilot`, `agy`). |
50
50
  | `ARIZE_SKIP_NPX=1` | `start.sh` / `start.ps1` | Force the shell path even when Node/npx is available. |
51
- | `ARIZE_PROMPT_URL=<url>` | `start.sh` / `start.ps1` | Fetch the onboarding prompt from a custom URL (supports `file://`). |
51
+ | `ARIZE_PROMPT_MANIFEST_URL=<url>` | `start.sh` / `start.ps1` | Fetch the onboarding prompt manifest from a custom URL. |
52
52
  | `ARIZE_ONBOARDING_DIR=<dir>` | all three | Stage the prompt somewhere other than `~/.arize/onboarding`. |
53
53
 
54
54
  The shell launchers also accept `--agent <id>`.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "evals",
3
- "version": "2.10.0",
3
+ "version": "2.11.0",
4
4
  "description": "Arize AX onboarding — instrument your app with tracing via your coding agent",
5
5
  "type": "module",
6
6
  "main": "cli.js",
@@ -10,8 +10,10 @@
10
10
  "scripts": {
11
11
  "postinstall": "node -e \"console.log('Arize evals installed — run: npx evals')\"",
12
12
  "start": "node cli.js",
13
- "test": "node --test",
13
+ "test": "node --test && npm run verify:prompt-manifest",
14
14
  "build:wheel": "node scripts/build-harness-wheel.mjs",
15
+ "build:prompt-manifest": "node scripts/generate-prompt-manifest.mjs",
16
+ "verify:prompt-manifest": "node scripts/verify-prompt-manifest.mjs",
15
17
  "prepack": "npm run build:wheel"
16
18
  },
17
19
  "dependencies": {
@@ -27,6 +29,7 @@
27
29
  "analytics.js",
28
30
  "track-event.mjs",
29
31
  "onboarding-prompt.md",
32
+ "prompt-manifest.json",
30
33
  "start.sh",
31
34
  "start.ps1",
32
35
  "vendor/"
@@ -0,0 +1,9 @@
1
+ {
2
+ "key_id": "2026-09-18",
3
+ "minimum_ax_cli_version": "0.35.0",
4
+ "prompt_sha256": "fd0582dd4fb125a2b948d901d76f1e80b775599d1e8b23a886db4a9fbbfdc056",
5
+ "prompt_url": "https://cdn.jsdelivr.net/npm/evals@2.11.0/onboarding-prompt.md",
6
+ "revision": "evals@2.11.0",
7
+ "schema_version": 1,
8
+ "signature": "H6yB6gs8+8y30/EYWnjQrJy6OV68AM7ktosqpJJqr/udmRwuSNzndcXmVGGHrhDN/nwcCB/Z0C6pZ8f2GJJ6Cw=="
9
+ }
package/start.ps1 CHANGED
@@ -24,8 +24,8 @@ $ErrorActionPreference = 'Stop'
24
24
 
25
25
  # The prompt ships inside the public `evals` npm package; jsDelivr serves package
26
26
  # files over HTTP, so it's fetchable even though the source repo is private.
27
- # Override with $env:ARIZE_PROMPT_URL if needed.
28
- $PromptUrl = if ($env:ARIZE_PROMPT_URL) { $env:ARIZE_PROMPT_URL } else { 'https://cdn.jsdelivr.net/npm/evals/onboarding-prompt.md' }
27
+ # Override the manifest URL with $env:ARIZE_PROMPT_MANIFEST_URL if needed.
28
+ $PromptManifestUrl = if ($env:ARIZE_PROMPT_MANIFEST_URL) { $env:ARIZE_PROMPT_MANIFEST_URL } else { 'https://cdn.jsdelivr.net/npm/evals/prompt-manifest.json' }
29
29
  $TrackUrl = if ($env:ARIZE_TRACK_URL) { $env:ARIZE_TRACK_URL } else { 'https://cdn.jsdelivr.net/npm/evals/track-event.mjs' }
30
30
  $AnalyticsUrl = if ($env:ARIZE_ANALYTICS_URL) { $env:ARIZE_ANALYTICS_URL } else { 'https://cdn.jsdelivr.net/npm/evals/analytics.js' }
31
31
  $AnalyticsEndpoint = if ($env:ARIZE_EVALS_ANALYTICS_URL) { $env:ARIZE_EVALS_ANALYTICS_URL } else { 'https://app.arize.com/api/analytics/npx-evals' }
@@ -184,7 +184,7 @@ function Clear-PromptDir($dir) {
184
184
  if (-not $ours) { return $false }
185
185
  if (-not (Clear-BundleDir $sub.FullName)) { return $false }
186
186
  }
187
- foreach ($name in @('onboarding-prompt.md', 'harness.env', 'track-event.mjs', 'analytics.js')) {
187
+ foreach ($name in @('onboarding-prompt.md', 'harness.env', '.prompt-manifest', 'track-event.mjs', 'analytics.js')) {
188
188
  Remove-Item -LiteralPath (Join-Path $dir $name) -Force -ErrorAction SilentlyContinue
189
189
  }
190
190
  # Anything left is not ours.
@@ -222,13 +222,48 @@ if (-not $promptDir) {
222
222
  $promptFile = Join-Path $promptDir 'onboarding-prompt.md'
223
223
 
224
224
  Write-Host "Fetching the onboarding prompt..."
225
+ # This bootstrap verifies the prompt digest but cannot independently verify the
226
+ # manifest signature on every supported PowerShell runtime. Its trust root is TLS to jsDelivr.
225
227
  try {
226
- Invoke-RestMethod -Uri $PromptUrl -OutFile $promptFile
228
+ $manifestRaw = (Invoke-WebRequest -Uri $PromptManifestUrl -UseBasicParsing).Content
227
229
  } catch {
228
- Write-Host "Failed to download the onboarding prompt from $PromptUrl" -ForegroundColor Red
230
+ Write-Host "Failed to download the onboarding prompt manifest." -ForegroundColor Red
229
231
  Write-Host "Check your connection and try again."
230
232
  exit 1
231
233
  }
234
+ try {
235
+ if ([regex]::Matches($manifestRaw, '"prompt_url"\s*:').Count -ne 1 -or
236
+ [regex]::Matches($manifestRaw, '"prompt_sha256"\s*:').Count -ne 1) {
237
+ throw 'duplicate manifest field'
238
+ }
239
+ $promptManifest = $manifestRaw | ConvertFrom-Json
240
+ $allowLocalPromptTest = $env:ARIZE_ALLOW_LOCAL_PROMPT_TEST -eq '1' -and $env:ARIZE_PROMPT_MANIFEST_URL
241
+ $validPromptUrl = if ($allowLocalPromptTest) {
242
+ $promptManifest.prompt_url -match '^http://127\.0\.0\.1:[0-9]+/onboarding-prompt\.md$'
243
+ } else {
244
+ $promptManifest.prompt_url -match '^https://cdn\.jsdelivr\.net/npm/evals@[^/]+/onboarding-prompt\.md$'
245
+ }
246
+ if ($promptManifest.schema_version -ne 1 -or
247
+ -not $validPromptUrl -or
248
+ $promptManifest.prompt_sha256 -notmatch '^[0-9a-fA-F]{64}$') {
249
+ throw 'invalid onboarding prompt manifest'
250
+ }
251
+ } catch {
252
+ Write-Host "The onboarding prompt manifest is invalid." -ForegroundColor Red
253
+ exit 1
254
+ }
255
+ try {
256
+ Invoke-RestMethod -Uri $promptManifest.prompt_url -OutFile $promptFile
257
+ } catch {
258
+ Write-Host "Failed to download the onboarding prompt." -ForegroundColor Red
259
+ Write-Host "Check your connection and try again."
260
+ exit 1
261
+ }
262
+ $actualPromptSha256 = (Get-FileHash -Path $promptFile -Algorithm SHA256).Hash.ToLower()
263
+ if ($actualPromptSha256 -ne $promptManifest.prompt_sha256.ToLower()) {
264
+ Write-Host "The onboarding prompt digest did not match its manifest." -ForegroundColor Red
265
+ exit 1
266
+ }
232
267
 
233
268
  # Best-effort: agent runs these before OAuth. Missing files just skip the ping.
234
269
  try { Invoke-RestMethod -Uri $TrackUrl -OutFile (Join-Path $promptDir 'track-event.mjs') } catch {}
package/start.sh CHANGED
@@ -20,8 +20,8 @@ set -euo pipefail
20
20
 
21
21
  # The prompt ships inside the public `evals` npm package; jsDelivr serves package
22
22
  # files over HTTP, so it's fetchable even though the source repo is private.
23
- # Override with ARIZE_PROMPT_URL if needed.
24
- PROMPT_URL="${ARIZE_PROMPT_URL:-https://cdn.jsdelivr.net/npm/evals/onboarding-prompt.md}"
23
+ # Override the manifest URL with ARIZE_PROMPT_MANIFEST_URL if needed.
24
+ PROMPT_MANIFEST_URL="${ARIZE_PROMPT_MANIFEST_URL:-https://cdn.jsdelivr.net/npm/evals/prompt-manifest.json}"
25
25
  TRACK_URL="${ARIZE_TRACK_URL:-https://cdn.jsdelivr.net/npm/evals/track-event.mjs}"
26
26
  ANALYTICS_URL="${ARIZE_ANALYTICS_URL:-https://cdn.jsdelivr.net/npm/evals/analytics.js}"
27
27
  ANALYTICS_ENDPOINT="${ARIZE_EVALS_ANALYTICS_URL:-https://app.arize.com/api/analytics/npx-evals}"
@@ -214,7 +214,7 @@ clear_prompt_dir() {
214
214
  for sub in "$1"/arize-offline "$1"/.staging*; do
215
215
  [ -d "$sub" ] && clear_bundle_dir "$sub"
216
216
  done
217
- rm -f "$1/onboarding-prompt.md" "$1/harness.env" \
217
+ rm -f "$1/onboarding-prompt.md" "$1/harness.env" "$1/.prompt-manifest" \
218
218
  "$1/track-event.mjs" "$1/analytics.js"
219
219
  # Anything left is not ours: bail out and let the caller fall back.
220
220
  rmdir "$1" 2>/dev/null || { [ -z "$(ls -A "$1" 2>/dev/null)" ]; return $?; }
@@ -253,12 +253,61 @@ else
253
253
  exit 1
254
254
  fi
255
255
 
256
+ MANIFEST_FILE="$PROMPT_DIR/.prompt-manifest"
257
+ # This bootstrap verifies the prompt digest but cannot independently verify the
258
+ # manifest signature on every supported shell. Its trust root is TLS to jsDelivr.
256
259
  echo "Fetching the onboarding prompt…"
260
+ if ! fetch "$PROMPT_MANIFEST_URL" "$MANIFEST_FILE"; then
261
+ echo "Failed to download the onboarding prompt manifest." >&2
262
+ echo "Check your connection and try again." >&2
263
+ exit 1
264
+ fi
265
+
266
+ manifest_value() {
267
+ values="$(sed -n "s/^[[:space:]]*\"$1\"[[:space:]]*:[[:space:]]*\"\([^\"]*\)\"[[:space:]]*,\{0,1\}[[:space:]]*$/\1/p" "$MANIFEST_FILE")"
268
+ [ "$(printf '%s\n' "$values" | sed '/^$/d' | wc -l | tr -d ' ')" -eq 1 ] || return 1
269
+ printf '%s' "$values"
270
+ }
271
+
272
+ PROMPT_URL="$(manifest_value prompt_url)" || { echo "The onboarding prompt manifest is invalid." >&2; exit 1; }
273
+ PROMPT_SHA256="$(manifest_value prompt_sha256)" || { echo "The onboarding prompt manifest is invalid." >&2; exit 1; }
274
+ rm -f "$MANIFEST_FILE"
275
+ if [ "${ARIZE_ALLOW_LOCAL_PROMPT_TEST:-}" = "1" ] \
276
+ && [ -n "${ARIZE_PROMPT_MANIFEST_URL:-}" ]; then
277
+ case "$PROMPT_URL" in
278
+ http://127.0.0.1:*/onboarding-prompt.md) ;;
279
+ *) echo "The local prompt test URL must use 127.0.0.1 and onboarding-prompt.md." >&2; exit 1 ;;
280
+ esac
281
+ else
282
+ case "$PROMPT_URL" in
283
+ https://cdn.jsdelivr.net/npm/evals@*/onboarding-prompt.md) ;;
284
+ *) echo "The onboarding prompt manifest has an invalid prompt URL." >&2; exit 1 ;;
285
+ esac
286
+ fi
287
+ case "$PROMPT_SHA256" in
288
+ *[!0-9a-fA-F]*) echo "The onboarding prompt manifest has an invalid digest." >&2; exit 1 ;;
289
+ esac
290
+ if [ "${#PROMPT_SHA256}" -ne 64 ]; then
291
+ echo "The onboarding prompt manifest has an invalid digest." >&2
292
+ exit 1
293
+ fi
257
294
  if ! fetch "$PROMPT_URL" "$PROMPT_FILE"; then
258
- echo "Failed to download the onboarding prompt from $PROMPT_URL" >&2
295
+ echo "Failed to download the onboarding prompt." >&2
259
296
  echo "Check your connection and try again." >&2
260
297
  exit 1
261
298
  fi
299
+ if command -v shasum >/dev/null 2>&1; then
300
+ ACTUAL_SHA256="$(shasum -a 256 "$PROMPT_FILE" | awk '{print $1}')"
301
+ elif command -v sha256sum >/dev/null 2>&1; then
302
+ ACTUAL_SHA256="$(sha256sum "$PROMPT_FILE" | awk '{print $1}')"
303
+ else
304
+ echo "Need shasum or sha256sum to verify the onboarding prompt." >&2
305
+ exit 1
306
+ fi
307
+ if [ "$ACTUAL_SHA256" != "$PROMPT_SHA256" ]; then
308
+ echo "The onboarding prompt digest did not match its manifest." >&2
309
+ exit 1
310
+ fi
262
311
 
263
312
  # Best-effort: agent runs these before OAuth. Missing files just skip the ping.
264
313
  fetch "$TRACK_URL" "$PROMPT_DIR/track-event.mjs" 2>/dev/null || true
package/vendor/MANIFEST CHANGED
@@ -1,6 +1,6 @@
1
1
  a9cede65f98d3415b13e1c6a437d0fdee27286bfff0186dd72bb65d9869b7864 LICENSE-coding-harness-tracing
2
2
  62f22742b58a1a33014a2b6b706588a8d7e2a88ae7bd1a6ebe8c992928483775 certifi-2026.7.22-py3-none-any.whl
3
- 9f44b6e34618b87ab64f6aa48fd300bbfc6122fd4aca195122f68973747cad61 coding_harness_tracing-0.1.0-py3-none-any.whl
3
+ 6fa310dbfb392719881f8c9459d9d2a61c958e39c4d0d4e9c4ac29c7cb7403ce coding_harness_tracing-0.1.0-py3-none-any.whl
4
4
  aca14e09ca99c253d2a142e2d5c5c38c8c7cf90840d3cb10b241c29929871fa4 harness-install.bat
5
5
  a7ba18a98280e236b20ab4cb9f8a4006068b454586a2af50bf23fb0dbe70583d harness-install.sh
6
6
  b81ee9561e9ca4004139c6cbba3a238c32b03e4894671e181b671e8cb8425d61 python_dotenv-1.2.1-py3-none-any.whl
@@ -1,11 +1,11 @@
1
1
  {
2
2
  "repo": "https://github.com/Arize-ai/coding-harness-tracing",
3
3
  "ref": "main",
4
- "resolvedSha": "771ad555aab24ea2fd54a41b22936b6521156b26",
4
+ "resolvedSha": "62609f080d6a6b4786114e45dafd90a2945f2233",
5
5
  "source": "git",
6
6
  "wheel": "coding_harness_tracing-0.1.0-py3-none-any.whl",
7
7
  "wheelVersion": "0.1.0",
8
- "wheelSha256": "9f44b6e34618b87ab64f6aa48fd300bbfc6122fd4aca195122f68973747cad61",
8
+ "wheelSha256": "6fa310dbfb392719881f8c9459d9d2a61c958e39c4d0d4e9c4ac29c7cb7403ce",
9
9
  "files": [
10
10
  "LICENSE-coding-harness-tracing",
11
11
  "MANIFEST",