evals 2.5.0 → 2.7.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 +12 -5
- package/bin.js +43 -0
- package/cli.js +226 -60
- package/onboarding-prompt.md +118 -68
- package/package.json +6 -3
- package/start.ps1 +168 -66
- package/start.sh +99 -17
- package/vendor/MANIFEST +1 -1
- package/vendor/coding_harness_tracing-0.1.0-py3-none-any.whl +0 -0
- package/vendor/harness-pin.lock.json +1 -1
package/start.ps1
CHANGED
|
@@ -32,18 +32,33 @@ $VendorUrl = if ($env:ARIZE_VENDOR_URL) { $env:ARIZE_VENDOR_URL } else { 'https:
|
|
|
32
32
|
# Prefer the richer, bundled-prompt `npx evals` experience when Node is present.
|
|
33
33
|
# This script is the no-npm fallback; if npx exists, hand off to it.
|
|
34
34
|
# Set $env:ARIZE_SKIP_NPX=1 to force this shell path even when npx is available.
|
|
35
|
+
#
|
|
36
|
+
# Only hand off on Node 20+, which is what the Ink UI needs (see bin.js). Handing
|
|
37
|
+
# an older Node to npx would swap a working flow for a hard failure — this script
|
|
38
|
+
# needs no Node at all, so stay here instead. Keep the floor in step with bin.js.
|
|
35
39
|
if (-not $env:ARIZE_SKIP_NPX -and (Get-Command npx -ErrorAction SilentlyContinue)) {
|
|
36
|
-
|
|
37
|
-
|
|
40
|
+
$nodeMajor = 0
|
|
41
|
+
$nodeVersion = $null
|
|
42
|
+
if (Get-Command node -ErrorAction SilentlyContinue) {
|
|
43
|
+
$nodeVersion = (& node --version 2>$null)
|
|
44
|
+
if ($nodeVersion -match '^v?(\d+)') { $nodeMajor = [int]$Matches[1] }
|
|
45
|
+
}
|
|
46
|
+
if ($nodeMajor -ge 20) {
|
|
47
|
+
npx --yes evals
|
|
48
|
+
exit $LASTEXITCODE
|
|
49
|
+
}
|
|
50
|
+
$shown = if ($nodeVersion) { $nodeVersion } else { 'not found' }
|
|
51
|
+
Write-Host "Node $shown is too old for the npx UI — continuing without it."
|
|
52
|
+
Write-Host ""
|
|
38
53
|
}
|
|
39
54
|
|
|
40
55
|
# Supported agents: id -> label, install URL, and whether the REPL is seeded with `-i`.
|
|
41
56
|
$Agents = [ordered]@{
|
|
42
|
-
'claude' = @{ Label = 'Claude Code';
|
|
43
|
-
'codex' = @{ Label = 'OpenAI Codex';
|
|
44
|
-
'cursor-agent' = @{ Label = 'Cursor';
|
|
45
|
-
'copilot' = @{ Label = 'GitHub Copilot';
|
|
46
|
-
'
|
|
57
|
+
'claude' = @{ Label = 'Claude Code'; Install = 'https://docs.claude.com/en/docs/claude-code'; Flag = $null }
|
|
58
|
+
'codex' = @{ Label = 'OpenAI Codex'; Install = 'https://developers.openai.com/codex/cli'; Flag = $null }
|
|
59
|
+
'cursor-agent' = @{ Label = 'Cursor'; Install = 'https://docs.cursor.com/en/cli/overview'; Flag = $null }
|
|
60
|
+
'copilot' = @{ Label = 'GitHub Copilot'; Install = 'https://github.com/features/copilot/cli'; Flag = '-i' }
|
|
61
|
+
'agy' = @{ Label = 'Antigravity CLI'; Install = 'https://antigravity.google/docs/cli/getting-started'; Flag = '-i' }
|
|
47
62
|
}
|
|
48
63
|
|
|
49
64
|
function Test-Agent([string]$id) {
|
|
@@ -87,80 +102,167 @@ function Resolve-Agent {
|
|
|
87
102
|
# --- Welcome ---
|
|
88
103
|
Write-Host ""
|
|
89
104
|
Write-Host "Arize AX" -ForegroundColor Magenta -NoNewline
|
|
90
|
-
Write-Host " -
|
|
105
|
+
Write-Host " - Observability and Evals for Agentic AI" -ForegroundColor DarkGray
|
|
91
106
|
Write-Host ""
|
|
92
107
|
Write-Host "Let's get you tracing. I'll launch your coding agent with a guided prompt that"
|
|
93
108
|
Write-Host "walks you through signup, instrumenting your app, and seeing your first traces."
|
|
94
109
|
Write-Host ""
|
|
95
110
|
|
|
96
|
-
|
|
97
|
-
|
|
111
|
+
# No terminal on stdout? Then there is no picker to draw and nothing to launch, which
|
|
112
|
+
# is how testers keep reaching us: they type this command as a prompt and their coding
|
|
113
|
+
# agent runs it. Stage the prompt anyway and point the user at a terminal at the end.
|
|
114
|
+
if ([Console]::IsOutputRedirected) {
|
|
115
|
+
$chosen = $null
|
|
116
|
+
} else {
|
|
117
|
+
$chosen = Resolve-Agent
|
|
118
|
+
if (-not $chosen) { exit 1 }
|
|
119
|
+
}
|
|
98
120
|
|
|
99
121
|
# A directory, not a bare temp file: Step 4A looks for the offline bundle *beside*
|
|
100
122
|
# the prompt, so the prompt needs a directory of its own.
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
123
|
+
#
|
|
124
|
+
# ~/.arize/onboarding, not a temp path: the agent is asked to read a file outside
|
|
125
|
+
# its workspace, and a named path is an approval a human can grant with confidence.
|
|
126
|
+
# Sits beside Step 4A's own ~/.arize/harness install, which we must never touch.
|
|
127
|
+
#
|
|
128
|
+
# GetFolderPath('UserProfile') rather than $HOME: on Windows PowerShell 5.1 $HOME
|
|
129
|
+
# comes from HOMEDRIVE+HOMEPATH, which for domain users can point at a redirected
|
|
130
|
+
# network share that is slow or offline. This returns USERPROFILE on Windows and
|
|
131
|
+
# $HOME under PowerShell Core on macOS/Linux — one expression for both.
|
|
132
|
+
function Clear-BundleDir($dir) {
|
|
133
|
+
# Delete only what we stage, by name. Wheel filenames carry a version we can't
|
|
134
|
+
# know, so those go by extension, non-recursively, in this directory only.
|
|
135
|
+
Get-ChildItem -LiteralPath $dir -File -Filter '*.whl' -ErrorAction SilentlyContinue |
|
|
136
|
+
Remove-Item -Force -ErrorAction SilentlyContinue
|
|
137
|
+
foreach ($name in @('harness-install.sh', 'harness-install.bat', 'LICENSE-coding-harness-tracing', 'MANIFEST')) {
|
|
138
|
+
Remove-Item -LiteralPath (Join-Path $dir $name) -Force -ErrorAction SilentlyContinue
|
|
112
139
|
}
|
|
140
|
+
# No -Recurse anywhere: a non-empty directory fails here rather than taking
|
|
141
|
+
# something we didn't put there with it, and Remove-Item's habit of recursing
|
|
142
|
+
# through a directory junction can't bite us.
|
|
143
|
+
Remove-Item -LiteralPath $dir -Force -ErrorAction SilentlyContinue
|
|
144
|
+
return -not (Test-Path -LiteralPath $dir)
|
|
145
|
+
}
|
|
113
146
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
$
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
foreach ($line in Get-Content $manifestPath) {
|
|
131
|
-
if (-not $line.Trim()) { continue }
|
|
132
|
-
# MANIFEST is `shasum -a 256` format: "<sha256> <filename>".
|
|
133
|
-
$parts = $line -split '\s+', 2
|
|
134
|
-
$expected = $parts[0]
|
|
135
|
-
$name = $parts[1].Trim()
|
|
136
|
-
$dest = Join-Path $staging $name
|
|
137
|
-
Invoke-RestMethod -Uri "$VendorUrl/$name" -OutFile $dest
|
|
138
|
-
$actual = (Get-FileHash -Path $dest -Algorithm SHA256).Hash.ToLower()
|
|
139
|
-
if ($actual -ne $expected.ToLower()) {
|
|
140
|
-
throw "checksum mismatch for $name"
|
|
141
|
-
}
|
|
142
|
-
}
|
|
147
|
+
# -LiteralPath throughout: a home path containing [ or ] is a real wildcard
|
|
148
|
+
# footgun for the non-literal forms. Keep this list in step with cli.js
|
|
149
|
+
# OFFLINE_FILES and start.sh.
|
|
150
|
+
function Clear-PromptDir($dir) {
|
|
151
|
+
if (-not (Test-Path -LiteralPath $dir)) { return $true }
|
|
152
|
+
foreach ($sub in Get-ChildItem -LiteralPath $dir -Directory -Force -ErrorAction SilentlyContinue) {
|
|
153
|
+
$ours = ($sub.Name -eq 'arize-offline') -or $sub.Name.StartsWith('.staging')
|
|
154
|
+
if (-not $ours) { return $false }
|
|
155
|
+
if (-not (Clear-BundleDir $sub.FullName)) { return $false }
|
|
156
|
+
}
|
|
157
|
+
foreach ($name in @('onboarding-prompt.md', 'harness.env')) {
|
|
158
|
+
Remove-Item -LiteralPath (Join-Path $dir $name) -Force -ErrorAction SilentlyContinue
|
|
159
|
+
}
|
|
160
|
+
# Anything left is not ours.
|
|
161
|
+
return -not (Get-ChildItem -LiteralPath $dir -Force -ErrorAction SilentlyContinue)
|
|
162
|
+
}
|
|
143
163
|
|
|
144
|
-
|
|
164
|
+
$candidate = if ($env:ARIZE_ONBOARDING_DIR) {
|
|
165
|
+
$env:ARIZE_ONBOARDING_DIR
|
|
166
|
+
} else {
|
|
167
|
+
$profileDir = [Environment]::GetFolderPath('UserProfile')
|
|
168
|
+
if (-not $profileDir) { $profileDir = $HOME }
|
|
169
|
+
if ($profileDir) { Join-Path (Join-Path $profileDir '.arize') 'onboarding' } else { $null }
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
# Try the work and degrade, rather than probing for writability — a probe races
|
|
173
|
+
# and can't see a full disk. Covers a read-only home, a directory owned by another
|
|
174
|
+
# user, an offline redirected profile, and a file in there we refuse to delete.
|
|
175
|
+
$promptDir = $null
|
|
176
|
+
if ($candidate -and (Clear-PromptDir $candidate)) {
|
|
177
|
+
try {
|
|
178
|
+
New-Item -ItemType Directory -Path $candidate -Force -ErrorAction Stop | Out-Null
|
|
179
|
+
$promptDir = $candidate
|
|
145
180
|
} catch {
|
|
146
|
-
|
|
147
|
-
Write-Host " (not available — Step 4A will download the installer instead)"
|
|
181
|
+
$promptDir = $null
|
|
148
182
|
}
|
|
183
|
+
}
|
|
184
|
+
if (-not $promptDir) {
|
|
185
|
+
$promptDir = Join-Path ([System.IO.Path]::GetTempPath()) ("arize-onboarding-" + [System.Guid]::NewGuid().ToString('N').Substring(0, 8))
|
|
186
|
+
New-Item -ItemType Directory -Path $promptDir -Force | Out-Null
|
|
187
|
+
if ($candidate) {
|
|
188
|
+
Write-Host "Couldn't use $candidate — staging in $promptDir instead."
|
|
189
|
+
Write-Host "Instrumenting an app still works; tracing this coding agent (Step 4A) needs a writable home directory."
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
$promptFile = Join-Path $promptDir 'onboarding-prompt.md'
|
|
149
193
|
|
|
150
|
-
|
|
194
|
+
Write-Host "Fetching the onboarding prompt..."
|
|
195
|
+
try {
|
|
196
|
+
Invoke-RestMethod -Uri $PromptUrl -OutFile $promptFile
|
|
197
|
+
} catch {
|
|
198
|
+
Write-Host "Failed to download the onboarding prompt from $PromptUrl" -ForegroundColor Red
|
|
199
|
+
Write-Host "Check your connection and try again."
|
|
200
|
+
exit 1
|
|
201
|
+
}
|
|
151
202
|
|
|
152
|
-
|
|
153
|
-
|
|
203
|
+
# Fetch the bundled tracing harness so Step 4A can install it without piping a
|
|
204
|
+
# downloaded script into a shell — the thing auto-approval permission
|
|
205
|
+
# classifiers refuse. `npx evals` ships these files; this path pulls them from
|
|
206
|
+
# the CDN, using vendor/MANIFEST because a launcher cannot glob a CDN and must
|
|
207
|
+
# not hardcode versioned wheel names.
|
|
208
|
+
#
|
|
209
|
+
# Best-effort throughout. Any failure leaves no arize-offline directory and the
|
|
210
|
+
# prompt takes its documented network path instead. Staged under a temp name and
|
|
211
|
+
# renamed, so the directory Step 4A keys off only ever appears complete.
|
|
212
|
+
Write-Host "Fetching the tracing harness..."
|
|
213
|
+
$staging = Join-Path $promptDir '.staging'
|
|
214
|
+
try {
|
|
215
|
+
New-Item -ItemType Directory -Path $staging -Force | Out-Null
|
|
216
|
+
$manifestPath = Join-Path $staging 'MANIFEST'
|
|
217
|
+
Invoke-RestMethod -Uri "$VendorUrl/MANIFEST" -OutFile $manifestPath
|
|
154
218
|
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
219
|
+
foreach ($line in Get-Content $manifestPath) {
|
|
220
|
+
if (-not $line.Trim()) { continue }
|
|
221
|
+
# MANIFEST is `shasum -a 256` format: "<sha256> <filename>".
|
|
222
|
+
$parts = $line -split '\s+', 2
|
|
223
|
+
$expected = $parts[0]
|
|
224
|
+
$name = $parts[1].Trim()
|
|
225
|
+
$dest = Join-Path $staging $name
|
|
226
|
+
Invoke-RestMethod -Uri "$VendorUrl/$name" -OutFile $dest
|
|
227
|
+
$actual = (Get-FileHash -Path $dest -Algorithm SHA256).Hash.ToLower()
|
|
228
|
+
if ($actual -ne $expected.ToLower()) {
|
|
229
|
+
throw "checksum mismatch for $name"
|
|
230
|
+
}
|
|
163
231
|
}
|
|
164
|
-
|
|
165
|
-
|
|
232
|
+
|
|
233
|
+
Move-Item -LiteralPath $staging -Destination (Join-Path $promptDir 'arize-offline')
|
|
234
|
+
} catch {
|
|
235
|
+
Clear-BundleDir $staging | Out-Null
|
|
236
|
+
Write-Host " (not available — Step 4A will download the installer instead)"
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
# Single quotes around the path: the home directory is likelier to contain a space
|
|
240
|
+
# than the old temp path was, and single quotes survive the console handoff below
|
|
241
|
+
# where embedded double quotes would not.
|
|
242
|
+
# No "in this project": this may well be run from a home directory, and Step 4 is
|
|
243
|
+
# what scopes the work. Keep this wording in step with cli.js and start.sh.
|
|
244
|
+
$seed = "Read the file '$promptFile' and follow it to set up Arize AX tracing, walking me through each step and asking me questions as needed."
|
|
245
|
+
|
|
246
|
+
if (-not $chosen) {
|
|
247
|
+
# Addressed to the person, two lines, recommendation first - see the note in cli.js.
|
|
248
|
+
Write-Host "Re-run this in a terminal to set up Arize AX tracing - this is not a terminal, so nothing was set up."
|
|
249
|
+
Write-Host "The prompt is at $promptFile if you'd rather have your agent follow it."
|
|
250
|
+
exit 0
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
Write-Host ("Launching {0}..." -f $Agents[$chosen].Label)
|
|
254
|
+
Write-Host ""
|
|
255
|
+
|
|
256
|
+
# Launch interactive + seeded. No skip-permissions — the agent's approval
|
|
257
|
+
# model and the prompt's own approval gate must stay intact. External commands
|
|
258
|
+
# attach to the console, so the agent gets a real terminal.
|
|
259
|
+
#
|
|
260
|
+
# No try/finally around this any more: the staging directory persists so the agent
|
|
261
|
+
# can still reach the prompt in a session that outlives this script. It is cleared
|
|
262
|
+
# at the start of the next launch instead.
|
|
263
|
+
$flag = $Agents[$chosen].Flag
|
|
264
|
+
if ($flag) {
|
|
265
|
+
& $chosen $flag $seed
|
|
266
|
+
} else {
|
|
267
|
+
& $chosen $seed
|
|
166
268
|
}
|
package/start.sh
CHANGED
|
@@ -28,20 +28,35 @@ VENDOR_URL="${ARIZE_VENDOR_URL:-https://cdn.jsdelivr.net/npm/evals/vendor}"
|
|
|
28
28
|
# Prefer the richer, bundled-prompt `npx evals` experience when Node is present.
|
|
29
29
|
# This shell script is the no-npm fallback; if npx exists, hand off to it.
|
|
30
30
|
# Set ARIZE_SKIP_NPX=1 to force this shell path even when npx is available.
|
|
31
|
+
#
|
|
32
|
+
# Only hand off on Node 20+, which is what the Ink UI needs (see bin.js). Handing
|
|
33
|
+
# an older Node to npx would swap a working flow for a hard failure — this script
|
|
34
|
+
# needs no Node at all, so stay here instead. Keep the floor in step with bin.js.
|
|
35
|
+
node_major() {
|
|
36
|
+
command -v node >/dev/null 2>&1 || return 1
|
|
37
|
+
v="$(node --version 2>/dev/null)" || return 1
|
|
38
|
+
v="${v#v}"
|
|
39
|
+
echo "${v%%.*}"
|
|
40
|
+
}
|
|
31
41
|
if [ -z "${ARIZE_SKIP_NPX:-}" ] && command -v npx >/dev/null 2>&1; then
|
|
32
|
-
|
|
42
|
+
major="$(node_major || echo 0)"
|
|
43
|
+
if [ "${major:-0}" -ge 20 ] 2>/dev/null; then
|
|
44
|
+
exec npx --yes evals
|
|
45
|
+
fi
|
|
46
|
+
echo "Node $(node --version 2>/dev/null || echo 'not found') is too old for the npx UI — continuing without it."
|
|
47
|
+
echo
|
|
33
48
|
fi
|
|
34
49
|
|
|
35
50
|
# Supported agents: id | display label | argv to start the REPL seeded with a prompt.
|
|
36
51
|
# The seed prompt is appended as the final argument at launch.
|
|
37
|
-
AGENT_IDS=(claude codex cursor-agent copilot
|
|
52
|
+
AGENT_IDS=(claude codex cursor-agent copilot agy)
|
|
38
53
|
agent_label() {
|
|
39
54
|
case "$1" in
|
|
40
55
|
claude) echo "Claude Code" ;;
|
|
41
56
|
codex) echo "OpenAI Codex" ;;
|
|
42
57
|
cursor-agent) echo "Cursor" ;;
|
|
43
58
|
copilot) echo "GitHub Copilot" ;;
|
|
44
|
-
|
|
59
|
+
agy) echo "Antigravity CLI" ;;
|
|
45
60
|
*) echo "$1" ;;
|
|
46
61
|
esac
|
|
47
62
|
}
|
|
@@ -51,7 +66,7 @@ agent_install_url() {
|
|
|
51
66
|
codex) echo "https://developers.openai.com/codex/cli" ;;
|
|
52
67
|
cursor-agent) echo "https://docs.cursor.com/en/cli/overview" ;;
|
|
53
68
|
copilot) echo "https://github.com/features/copilot/cli" ;;
|
|
54
|
-
|
|
69
|
+
agy) echo "https://antigravity.google/docs/cli/getting-started" ;;
|
|
55
70
|
esac
|
|
56
71
|
}
|
|
57
72
|
|
|
@@ -62,7 +77,7 @@ while [[ $# -gt 0 ]]; do
|
|
|
62
77
|
--agent) AGENT="${2:-}"; shift 2 ;;
|
|
63
78
|
--agent=*) AGENT="${1#*=}"; shift ;;
|
|
64
79
|
-h|--help)
|
|
65
|
-
echo "Usage: start.sh [--agent <claude|codex|cursor-agent|copilot|
|
|
80
|
+
echo "Usage: start.sh [--agent <claude|codex|cursor-agent|copilot|agy>]"
|
|
66
81
|
exit 0 ;;
|
|
67
82
|
*) echo "Unknown argument: $1" >&2; exit 1 ;;
|
|
68
83
|
esac
|
|
@@ -70,11 +85,11 @@ done
|
|
|
70
85
|
|
|
71
86
|
# --- Welcome ---
|
|
72
87
|
if [ -t 1 ] && [ "${TERM:-}" != "dumb" ]; then
|
|
73
|
-
_pink=$'\033[1;38;2;
|
|
88
|
+
_pink=$'\033[1;38;2;236;32;136m'; _dim=$'\033[2m'; _reset=$'\033[0m'
|
|
74
89
|
else
|
|
75
90
|
_pink=""; _dim=""; _reset=""
|
|
76
91
|
fi
|
|
77
|
-
printf '\n%sArize AX%s %s—
|
|
92
|
+
printf '\n%sArize AX%s %s— Observability and Evals for Agentic AI%s\n\n' "$_pink" "$_reset" "$_dim" "$_reset"
|
|
78
93
|
printf "Let's get you tracing. I'll launch your coding agent with a guided prompt that\nwalks you through signup, instrumenting your app, and seeing your first traces.\n\n"
|
|
79
94
|
|
|
80
95
|
# Detect installed agents (PATH lookup only — never executes them).
|
|
@@ -133,15 +148,72 @@ choose_agent() {
|
|
|
133
148
|
done
|
|
134
149
|
}
|
|
135
150
|
|
|
136
|
-
|
|
151
|
+
# No terminal on stdout? Then there is no picker to draw and nothing to launch, which
|
|
152
|
+
# is how testers keep reaching us: they type this command as a prompt and their coding
|
|
153
|
+
# agent runs it. Stage the prompt anyway and point the user at a terminal at the end.
|
|
154
|
+
if [[ ! -t 1 ]]; then
|
|
155
|
+
CHOSEN=""
|
|
156
|
+
else
|
|
157
|
+
CHOSEN="$(choose_agent)" || exit 1
|
|
158
|
+
fi
|
|
137
159
|
|
|
138
160
|
# A directory, not a bare temp file: Step 4A looks for the offline bundle *beside*
|
|
139
|
-
# the prompt, so the prompt needs a directory of its own
|
|
140
|
-
#
|
|
141
|
-
|
|
161
|
+
# the prompt, so the prompt needs a directory of its own.
|
|
162
|
+
#
|
|
163
|
+
# ~/.arize/onboarding, not a temp path: the agent is asked to read a file outside
|
|
164
|
+
# its workspace, and that approval is one a human can grant with confidence for a
|
|
165
|
+
# named path but not for /tmp/arize-onboarding-8fJ2x1. Sits beside Step 4A's own
|
|
166
|
+
# ~/.arize/harness install, which we must never touch.
|
|
167
|
+
#
|
|
168
|
+
# Cleared at launch and left in place afterwards — no EXIT trap — so the agent can
|
|
169
|
+
# still reach the prompt in a session that outlives this script, and so we can
|
|
170
|
+
# exec rather than waiting on a child just to clean up.
|
|
171
|
+
clear_bundle_dir() {
|
|
172
|
+
# Delete only what we stage, by name. Wheel filenames carry a version we can't
|
|
173
|
+
# know, so those go by extension, non-recursively, in this directory only.
|
|
174
|
+
rm -f "$1"/*.whl
|
|
175
|
+
rm -f "$1/harness-install.sh" "$1/harness-install.bat" \
|
|
176
|
+
"$1/LICENSE-coding-harness-tracing" "$1/MANIFEST"
|
|
177
|
+
# rmdir, never rm -r: a non-empty directory fails here instead of taking
|
|
178
|
+
# something we didn't put there down with it.
|
|
179
|
+
rmdir "$1" 2>/dev/null
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
# Never a recursive delete. Worst case on a bad path is unlinking a few names that
|
|
183
|
+
# don't exist. Keep this list in step with cli.js OFFLINE_FILES and start.ps1.
|
|
184
|
+
clear_prompt_dir() {
|
|
185
|
+
[ -d "$1" ] || return 0
|
|
186
|
+
for sub in "$1"/arize-offline "$1"/.staging*; do
|
|
187
|
+
[ -d "$sub" ] && clear_bundle_dir "$sub"
|
|
188
|
+
done
|
|
189
|
+
rm -f "$1/onboarding-prompt.md" "$1/harness.env"
|
|
190
|
+
# Anything left is not ours: bail out and let the caller fall back.
|
|
191
|
+
rmdir "$1" 2>/dev/null || { [ -z "$(ls -A "$1" 2>/dev/null)" ]; return $?; }
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
# $HOME unset (containers, cron, some CI) must degrade, never abort — hence
|
|
195
|
+
# ${HOME:-} and not ${HOME:?}. Same for a read-only home, a directory owned by a
|
|
196
|
+
# past `sudo`, or a full disk: try the work, fall back to a temp dir on failure.
|
|
197
|
+
PROMPT_DIR=""
|
|
198
|
+
if [ -n "${ARIZE_ONBOARDING_DIR:-}" ]; then
|
|
199
|
+
CANDIDATE="$ARIZE_ONBOARDING_DIR"
|
|
200
|
+
elif [ -n "${HOME:-}" ]; then
|
|
201
|
+
CANDIDATE="$HOME/.arize/onboarding"
|
|
202
|
+
else
|
|
203
|
+
CANDIDATE=""
|
|
204
|
+
fi
|
|
205
|
+
|
|
206
|
+
if [ -n "$CANDIDATE" ] && clear_prompt_dir "$CANDIDATE" \
|
|
207
|
+
&& mkdir -p "$CANDIDATE" 2>/dev/null && chmod 700 "$CANDIDATE" 2>/dev/null; then
|
|
208
|
+
PROMPT_DIR="$CANDIDATE"
|
|
209
|
+
else
|
|
210
|
+
PROMPT_DIR="$(mktemp -d "${TMPDIR:-/tmp}/arize-onboarding-XXXXXX")"
|
|
211
|
+
if [ -n "$CANDIDATE" ]; then
|
|
212
|
+
echo "Couldn't use $CANDIDATE — staging in $PROMPT_DIR instead."
|
|
213
|
+
echo "Instrumenting an app still works; tracing this coding agent (Step 4A) needs a writable home directory."
|
|
214
|
+
fi
|
|
215
|
+
fi
|
|
142
216
|
PROMPT_FILE="$PROMPT_DIR/onboarding-prompt.md"
|
|
143
|
-
cleanup() { rm -rf "$PROMPT_DIR"; }
|
|
144
|
-
trap cleanup EXIT
|
|
145
217
|
|
|
146
218
|
if command -v curl >/dev/null 2>&1; then
|
|
147
219
|
fetch() { curl -fsSL "$1" -o "$2"; }
|
|
@@ -198,18 +270,28 @@ if ! stage_offline_bundle; then
|
|
|
198
270
|
echo " (not available — Step 4A will download the installer instead)"
|
|
199
271
|
fi
|
|
200
272
|
|
|
201
|
-
|
|
273
|
+
# No "in this project": this may well be run from a home directory, and Step 4 is
|
|
274
|
+
# what scopes the work. Keep this wording in step with cli.js and start.ps1.
|
|
275
|
+
SEED="Read the file '$PROMPT_FILE' and follow it to set up Arize AX tracing, walking me through each step and asking me questions as needed."
|
|
276
|
+
|
|
277
|
+
if [[ -z "$CHOSEN" ]]; then
|
|
278
|
+
# Addressed to the person, two lines, recommendation first — see the note in cli.js.
|
|
279
|
+
echo "Re-run this in a terminal to set up Arize AX tracing — this is not a terminal, so nothing was set up."
|
|
280
|
+
echo "The prompt is at $PROMPT_FILE if you'd rather have your agent follow it."
|
|
281
|
+
exit 0
|
|
282
|
+
fi
|
|
202
283
|
|
|
203
284
|
echo "Launching $(agent_label "$CHOSEN")…"
|
|
204
285
|
echo
|
|
205
286
|
|
|
206
287
|
# Launch interactive + seeded, on the real terminal. No skip-permissions —
|
|
207
288
|
# the agent's approval model and the prompt's own approval gate must stay intact.
|
|
208
|
-
#
|
|
289
|
+
# exec, now that the staging directory persists and there is no EXIT trap to run:
|
|
290
|
+
# the agent replaces this shell, so signals and the exit code reach it directly.
|
|
209
291
|
run_agent() {
|
|
210
292
|
case "$CHOSEN" in
|
|
211
|
-
copilot|
|
|
212
|
-
*) "$CHOSEN" "$SEED" ;;
|
|
293
|
+
copilot|agy) exec "$CHOSEN" -i "$SEED" ;;
|
|
294
|
+
*) exec "$CHOSEN" "$SEED" ;;
|
|
213
295
|
esac
|
|
214
296
|
}
|
|
215
297
|
|
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
|
-
|
|
3
|
+
e8b1f9519ddf75de49fe5334e9df38e6f76d169fd34be2322e678cce9ecf01e0 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
|
|
Binary file
|
|
@@ -5,7 +5,7 @@
|
|
|
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": "
|
|
8
|
+
"wheelSha256": "e8b1f9519ddf75de49fe5334e9df38e6f76d169fd34be2322e678cce9ecf01e0",
|
|
9
9
|
"files": [
|
|
10
10
|
"LICENSE-coding-harness-tracing",
|
|
11
11
|
"MANIFEST",
|