pi-cursor-sdk 0.1.20 → 0.1.22
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/CHANGELOG.md +38 -0
- package/README.md +49 -9
- package/docs/cursor-dogfood-checklist.md +57 -0
- package/docs/cursor-live-smoke-checklist.md +115 -9
- package/docs/cursor-model-ux-spec.md +58 -18
- package/docs/cursor-native-tool-replay.md +15 -7
- package/docs/cursor-native-tool-visual-audit.md +104 -59
- package/docs/cursor-testing-lessons.md +8 -3
- package/docs/cursor-tool-surfaces.md +69 -0
- package/package.json +34 -10
- package/scripts/debug-provider-events.d.mts +59 -0
- package/scripts/debug-provider-events.mjs +70 -175
- package/scripts/debug-sdk-events.d.mts +90 -0
- package/scripts/debug-sdk-events.mjs +36 -98
- package/scripts/fixtures/plan-strip-shim/index.ts +12 -0
- package/scripts/isolated-cursor-smoke.sh +264 -102
- package/scripts/lib/cursor-child-process.d.mts +10 -0
- package/scripts/lib/cursor-child-process.mjs +50 -0
- package/scripts/lib/cursor-cli-args.d.mts +63 -0
- package/scripts/lib/cursor-cli-args.mjs +129 -0
- package/scripts/lib/cursor-script-fail.d.mts +1 -0
- package/scripts/lib/cursor-script-fail.mjs +13 -0
- package/scripts/lib/cursor-sdk-output-filter.d.mts +5 -0
- package/scripts/lib/cursor-smoke-env.d.mts +38 -0
- package/scripts/lib/cursor-smoke-env.mjs +81 -0
- package/scripts/lib/cursor-smoke-shell.sh +174 -0
- package/scripts/lib/cursor-visual-render.d.mts +15 -0
- package/scripts/lib/cursor-visual-render.mjs +131 -0
- package/scripts/probe-mcp-coldstart.mjs +20 -38
- package/scripts/refresh-cursor-model-snapshots.mjs +29 -65
- package/scripts/steering-rpc-smoke.mjs +170 -65
- package/scripts/tmux-live-smoke.sh +152 -98
- package/scripts/visual-tui-smoke.mjs +659 -0
- package/shared/cursor-sdk-event-debug-env.d.mts +12 -0
- package/shared/cursor-sdk-event-debug-env.mjs +13 -0
- package/shared/cursor-sensitive-text.d.mts +1 -0
- package/{scripts/lib/cursor-probe-utils.mjs → shared/cursor-sensitive-text.mjs} +1 -13
- package/shared/cursor-setting-sources.d.mts +5 -0
- package/shared/cursor-setting-sources.mjs +22 -0
- package/src/context.ts +21 -12
- package/src/cursor-bridge-contract.ts +1 -3
- package/src/cursor-incomplete-tool-visibility.ts +22 -5
- package/src/cursor-native-tool-display-registration.ts +63 -27
- package/src/cursor-native-tool-display-replay.ts +246 -144
- package/src/cursor-native-tool-display-state.ts +2 -0
- package/src/cursor-native-tool-display-tools.ts +149 -41
- package/src/cursor-provider-live-run-drain.ts +1 -52
- package/src/cursor-provider-run-finalizer.ts +237 -0
- package/src/cursor-provider-run-outcome.ts +149 -0
- package/src/cursor-provider-turn-api-key.ts +8 -0
- package/src/cursor-provider-turn-coordinator.ts +98 -446
- package/src/cursor-provider-turn-display-router.ts +216 -0
- package/src/cursor-provider-turn-emit.ts +59 -0
- package/src/cursor-provider-turn-finalize.ts +119 -0
- package/src/cursor-provider-turn-lifecycle-emitter.ts +97 -0
- package/src/cursor-provider-turn-message-offset.ts +15 -0
- package/src/cursor-provider-turn-prepare.ts +216 -0
- package/src/cursor-provider-turn-runner.ts +140 -0
- package/src/cursor-provider-turn-sdk-normalizer.ts +88 -0
- package/src/cursor-provider-turn-send.ts +103 -0
- package/src/cursor-provider-turn-shell-output.ts +107 -0
- package/src/cursor-provider-turn-tool-ledger.ts +126 -0
- package/src/cursor-provider-turn-types.ts +87 -0
- package/src/cursor-provider.ts +16 -504
- package/src/cursor-replay-activity-builders.ts +276 -0
- package/src/cursor-replay-source-names.ts +33 -0
- package/src/cursor-replay-summary-args.ts +191 -0
- package/src/cursor-replay-tool-details.ts +464 -0
- package/src/cursor-run-final-text.ts +56 -0
- package/src/cursor-sdk-abort-error-guard.ts +4 -0
- package/src/cursor-sdk-event-debug-constants.ts +14 -5
- package/src/cursor-sdk-event-debug.ts +2 -1
- package/src/cursor-sensitive-text.ts +3 -36
- package/src/cursor-session-agent.ts +3 -1
- package/src/cursor-session-compaction-prep.ts +19 -0
- package/src/cursor-setting-sources.ts +7 -10
- package/src/cursor-state.ts +232 -28
- package/src/cursor-tool-lifecycle.ts +9 -8
- package/src/cursor-tool-manifest.ts +41 -0
- package/src/cursor-tool-names.ts +18 -106
- package/src/cursor-tool-presentation-registry.ts +556 -0
- package/src/cursor-tool-transcript.ts +1 -1
- package/src/cursor-tool-visibility.ts +3 -27
- package/src/cursor-transcript-tool-formatters.ts +0 -59
- package/src/cursor-transcript-tool-specs.ts +158 -233
- package/src/cursor-transcript-utils.ts +0 -44
- package/src/cursor-web-tool-activity.ts +10 -60
- package/src/cursor-web-tool-args.ts +39 -0
- package/src/index.ts +8 -10
|
@@ -2,21 +2,32 @@
|
|
|
2
2
|
set -euo pipefail
|
|
3
3
|
|
|
4
4
|
ROOT="$(cd "$(dirname "$0")/.." && pwd)"
|
|
5
|
+
# shellcheck source=scripts/lib/cursor-smoke-shell.sh
|
|
6
|
+
. "$ROOT/scripts/lib/cursor-smoke-shell.sh"
|
|
7
|
+
|
|
5
8
|
SMOKE_DIR="${SMOKE_DIR:-/tmp/pi-cursor-sdk-live-smoke-$(date +%Y%m%dT%H%M%S)}"
|
|
6
9
|
SHELL_BIN="${SHELL:-/bin/bash}"
|
|
7
10
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
11
|
+
PI_BIN=""
|
|
12
|
+
NODE_BIN=""
|
|
13
|
+
NPM_BIN=""
|
|
14
|
+
RG_BIN=""
|
|
15
|
+
TMUX_BIN=""
|
|
16
|
+
ENV_BIN=""
|
|
17
|
+
SEALED_PATH=""
|
|
18
|
+
PI_BASE=()
|
|
19
|
+
DEBUG_ENV_UNSETS=()
|
|
20
|
+
BASE_ENV=()
|
|
21
|
+
NONE_ENV=()
|
|
22
|
+
DEFAULT_ENV=()
|
|
13
23
|
|
|
14
24
|
TMUX_SESSIONS=()
|
|
15
25
|
|
|
16
26
|
cleanup() {
|
|
17
27
|
local session
|
|
28
|
+
[[ -n "${TMUX_BIN:-}" ]] || return 0
|
|
18
29
|
for session in "${TMUX_SESSIONS[@]:-}"; do
|
|
19
|
-
|
|
30
|
+
"$TMUX_BIN" kill-session -t "$session" 2>/dev/null || true
|
|
20
31
|
done
|
|
21
32
|
}
|
|
22
33
|
trap cleanup EXIT
|
|
@@ -31,11 +42,13 @@ Usage:
|
|
|
31
42
|
|
|
32
43
|
Environment:
|
|
33
44
|
SMOKE_DIR Artifact directory. Defaults to /tmp/pi-cursor-sdk-live-smoke-<timestamp>.
|
|
34
|
-
CURSOR_API_KEY
|
|
45
|
+
CURSOR_API_KEY Optional fallback auth. Stored pi auth in ~/.pi/agent/auth.json is also supported.
|
|
35
46
|
|
|
36
47
|
Prerequisites:
|
|
37
|
-
pi, node, rg, tmux on PATH
|
|
48
|
+
pi, node, npm, rg, tmux on PATH
|
|
49
|
+
Resolved pi/node/npm/rg/tmux paths from the parent shell are reused in tmux-launched checks; pi shims run with the resolved node directory first on PATH.
|
|
38
50
|
timeout or gtimeout optional; bash process-group kill fallback is used when absent
|
|
51
|
+
Child pi runs clear Cursor SDK event-debug env; isolated cases force PI_CURSOR_SETTING_SOURCES=none and default-settings unsets it.
|
|
39
52
|
|
|
40
53
|
Coverage:
|
|
41
54
|
- prereq model listing
|
|
@@ -48,10 +61,15 @@ Coverage:
|
|
|
48
61
|
- JSONL assistant usage validation
|
|
49
62
|
|
|
50
63
|
Not covered here:
|
|
51
|
-
|
|
64
|
+
- canonical rendered-PNG visual smoke; collect separately with docs/cursor-native-tool-visual-audit.md
|
|
65
|
+
- bridge MCP
|
|
66
|
+
- standalone native replay
|
|
67
|
+
- abort/cancel cleanup
|
|
68
|
+
- packaging and isolated smoke
|
|
52
69
|
|
|
53
70
|
Options:
|
|
54
71
|
-h, --help Show this help.
|
|
72
|
+
--self-test Run sealed PATH/env probes without live Cursor auth.
|
|
55
73
|
|
|
56
74
|
Exit codes:
|
|
57
75
|
0 all partial checks passed
|
|
@@ -59,61 +77,16 @@ Exit codes:
|
|
|
59
77
|
EOF
|
|
60
78
|
}
|
|
61
79
|
|
|
62
|
-
log() {
|
|
63
|
-
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
fail() {
|
|
67
|
-
printf '[smoke] FAIL: %s\n' "$*" >&2
|
|
68
|
-
exit 1
|
|
69
|
-
}
|
|
80
|
+
log() { smoke_log "$@"; }
|
|
81
|
+
fail() { smoke_fail "$@"; }
|
|
82
|
+
run_with_timeout() { smoke_run_with_timeout "$@"; }
|
|
70
83
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
shift
|
|
78
|
-
if command -v timeout >/dev/null 2>&1; then
|
|
79
|
-
timeout "$timeout_secs" "$@"
|
|
80
|
-
return $?
|
|
81
|
-
fi
|
|
82
|
-
if command -v gtimeout >/dev/null 2>&1; then
|
|
83
|
-
gtimeout "$timeout_secs" "$@"
|
|
84
|
-
return $?
|
|
85
|
-
fi
|
|
86
|
-
|
|
87
|
-
local restore_monitor=0
|
|
88
|
-
case $- in
|
|
89
|
-
*m*) ;;
|
|
90
|
-
*)
|
|
91
|
-
restore_monitor=1
|
|
92
|
-
set -m
|
|
93
|
-
;;
|
|
94
|
-
esac
|
|
95
|
-
|
|
96
|
-
"$@" &
|
|
97
|
-
local pid=$!
|
|
98
|
-
(
|
|
99
|
-
sleep "$timeout_secs"
|
|
100
|
-
kill -TERM "-$pid" 2>/dev/null || kill -TERM "$pid" 2>/dev/null || true
|
|
101
|
-
sleep 2
|
|
102
|
-
kill -KILL "-$pid" 2>/dev/null || kill -KILL "$pid" 2>/dev/null || true
|
|
103
|
-
) &
|
|
104
|
-
local watcher=$!
|
|
105
|
-
local code=0
|
|
106
|
-
if wait "$pid"; then
|
|
107
|
-
code=0
|
|
108
|
-
else
|
|
109
|
-
code=$?
|
|
110
|
-
fi
|
|
111
|
-
kill "$watcher" 2>/dev/null || true
|
|
112
|
-
wait "$watcher" 2>/dev/null || true
|
|
113
|
-
if (( restore_monitor )); then
|
|
114
|
-
set +m
|
|
115
|
-
fi
|
|
116
|
-
return "$code"
|
|
84
|
+
build_smoke_env_arrays() {
|
|
85
|
+
smoke_build_cursor_sdk_event_debug_unsets
|
|
86
|
+
DEBUG_ENV_UNSETS=( "${SMOKE_CURSOR_SDK_EVENT_DEBUG_ENV_UNSETS[@]}" )
|
|
87
|
+
BASE_ENV=( "$ENV_BIN" "${DEBUG_ENV_UNSETS[@]}" "PATH=$SEALED_PATH" )
|
|
88
|
+
NONE_ENV=( "$ENV_BIN" "${DEBUG_ENV_UNSETS[@]}" "PATH=$SEALED_PATH" PI_CURSOR_SETTING_SOURCES=none )
|
|
89
|
+
DEFAULT_ENV=( "$ENV_BIN" "${DEBUG_ENV_UNSETS[@]}" -u PI_CURSOR_SETTING_SOURCES "PATH=$SEALED_PATH" )
|
|
117
90
|
}
|
|
118
91
|
|
|
119
92
|
tail_file() {
|
|
@@ -131,7 +104,7 @@ assert_file_contains() {
|
|
|
131
104
|
local file="$2"
|
|
132
105
|
local pattern="$3"
|
|
133
106
|
local label="$4"
|
|
134
|
-
if !
|
|
107
|
+
if ! "$RG_BIN" -q "$pattern" "$file"; then
|
|
135
108
|
printf '[smoke] %s missing %s in %s\n' "$name" "$label" "$file" >&2
|
|
136
109
|
printf '[smoke] %s transcript tail:\n' "$name" >&2
|
|
137
110
|
tail_file "$file" 120 >&2
|
|
@@ -153,7 +126,7 @@ run_direct_attempt() {
|
|
|
153
126
|
shift 4
|
|
154
127
|
rm -f "$stdout" "$stderr"
|
|
155
128
|
|
|
156
|
-
if run_with_timeout "$timeout_secs" "$@" >"$stdout" 2>"$stderr"; then
|
|
129
|
+
if run_with_timeout "$timeout_secs" "$@" </dev/null >"$stdout" 2>"$stderr"; then
|
|
157
130
|
return 0
|
|
158
131
|
fi
|
|
159
132
|
return $?
|
|
@@ -193,7 +166,7 @@ run_direct() {
|
|
|
193
166
|
else
|
|
194
167
|
code=$?
|
|
195
168
|
fi
|
|
196
|
-
if [[ "$code" == "0" ]] &&
|
|
169
|
+
if [[ "$code" == "0" ]] && "$RG_BIN" -q "$expected_pattern" "$stdout"; then
|
|
197
170
|
log "$name PASS"
|
|
198
171
|
return 0
|
|
199
172
|
fi
|
|
@@ -213,7 +186,7 @@ run_direct() {
|
|
|
213
186
|
log "$name retrying once after empty output with exit $code"
|
|
214
187
|
if run_direct_attempt "$name" "$timeout_secs" "$stdout" "$stderr" "$@"; then
|
|
215
188
|
local retry_code=0
|
|
216
|
-
if
|
|
189
|
+
if "$RG_BIN" -q "$expected_pattern" "$stdout"; then
|
|
217
190
|
log "$name PASS after retry (first exit $code; first stderr: $first_stderr)"
|
|
218
191
|
return 0
|
|
219
192
|
fi
|
|
@@ -259,21 +232,22 @@ run_tui_math_footer_poll() {
|
|
|
259
232
|
command="$(quote_command "$@")"
|
|
260
233
|
rm -f "$capture"
|
|
261
234
|
|
|
262
|
-
printf -v script '
|
|
235
|
+
printf -v script 'export PATH=%q
|
|
236
|
+
cd %q || exit 97
|
|
263
237
|
exec %s
|
|
264
|
-
' "$ROOT" "$command"
|
|
265
|
-
|
|
238
|
+
' "$SEALED_PATH" "$ROOT" "$command"
|
|
239
|
+
"$TMUX_BIN" new-session -d -s "$session" -x 120 -y 40 -- "$SHELL_BIN" -lc "$script"
|
|
266
240
|
TMUX_SESSIONS+=("$session")
|
|
267
241
|
|
|
268
242
|
local elapsed=0
|
|
269
243
|
local missing=""
|
|
270
244
|
while true; do
|
|
271
|
-
|
|
245
|
+
"$TMUX_BIN" capture-pane -pt "$session" >"$capture" 2>/dev/null || true
|
|
272
246
|
missing=""
|
|
273
|
-
|
|
274
|
-
|
|
247
|
+
"$RG_BIN" -q "SUM=42" "$capture" || missing="${missing} SUM=42"
|
|
248
|
+
"$RG_BIN" -q "\\(cursor\\) composer-2\\.5" "$capture" || missing="${missing} footer (cursor) composer-2.5"
|
|
275
249
|
if [[ -z "$missing" ]]; then
|
|
276
|
-
|
|
250
|
+
"$TMUX_BIN" kill-session -t "$session" 2>/dev/null || true
|
|
277
251
|
log "$name PASS"
|
|
278
252
|
return 0
|
|
279
253
|
fi
|
|
@@ -281,7 +255,7 @@ exec %s
|
|
|
281
255
|
sleep 2
|
|
282
256
|
elapsed=$((elapsed + 2))
|
|
283
257
|
if (( elapsed >= timeout_secs )); then
|
|
284
|
-
|
|
258
|
+
"$TMUX_BIN" kill-session -t "$session" 2>/dev/null || true
|
|
285
259
|
printf '[smoke] %s timed out after %ss; missing:%s\n' "$name" "$timeout_secs" "$missing" >&2
|
|
286
260
|
printf '[smoke] %s capture tail:\n' "$name" >&2
|
|
287
261
|
tail_file "$capture" 120 >&2
|
|
@@ -304,12 +278,13 @@ run_tmux() {
|
|
|
304
278
|
command="$(quote_command "$@")"
|
|
305
279
|
rm -f "$marker" "$stdout" "$stderr"
|
|
306
280
|
|
|
307
|
-
printf -v script '
|
|
281
|
+
printf -v script 'export PATH=%q
|
|
282
|
+
cd %q || exit 97
|
|
308
283
|
%s> %q 2> %q
|
|
309
284
|
code=$?
|
|
310
285
|
printf '\''%%s\n'\'' "$code" > %q
|
|
311
|
-
' "$ROOT" "$command" "$stdout" "$stderr" "$marker"
|
|
312
|
-
|
|
286
|
+
' "$SEALED_PATH" "$ROOT" "$command" "$stdout" "$stderr" "$marker"
|
|
287
|
+
"$TMUX_BIN" new-session -d -s "$session" -- "$SHELL_BIN" -lc "$script"
|
|
313
288
|
TMUX_SESSIONS+=("$session")
|
|
314
289
|
|
|
315
290
|
local elapsed=0
|
|
@@ -317,15 +292,15 @@ printf '\''%%s\n'\'' "$code" > %q
|
|
|
317
292
|
sleep 2
|
|
318
293
|
elapsed=$((elapsed + 2))
|
|
319
294
|
if (( elapsed >= timeout_secs )); then
|
|
320
|
-
|
|
321
|
-
|
|
295
|
+
"$TMUX_BIN" capture-pane -pt "$session" >"$SMOKE_DIR/${name}.capture.txt" || true
|
|
296
|
+
"$TMUX_BIN" kill-session -t "$session" 2>/dev/null || true
|
|
322
297
|
fail "$name timed out after ${timeout_secs}s (see ${name}.capture.txt)"
|
|
323
298
|
fi
|
|
324
299
|
done
|
|
325
300
|
|
|
326
301
|
local code
|
|
327
302
|
code="$(cat "$marker")"
|
|
328
|
-
|
|
303
|
+
"$TMUX_BIN" kill-session -t "$session" 2>/dev/null || true
|
|
329
304
|
if [[ "$code" != "0" ]]; then
|
|
330
305
|
if [[ "$dump_stderr_on_fail" == "1" ]]; then
|
|
331
306
|
cat "$stderr" >&2 || true
|
|
@@ -337,30 +312,109 @@ printf '\''%%s\n'\'' "$code" > %q
|
|
|
337
312
|
|
|
338
313
|
model_listed() {
|
|
339
314
|
local file="$1"
|
|
340
|
-
|
|
315
|
+
"$RG_BIN" -q "composer-2\\.5" "$file"
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
run_self_test() {
|
|
319
|
+
local temp_dir bin_dir fake_pi fake_node fake_node_marker env_capture hostile_path captured_path node_dir name
|
|
320
|
+
temp_dir="$(mktemp -d /tmp/pi-cursor-sdk-live-smoke-self-test.XXXXXX)"
|
|
321
|
+
trap 'rm -rf "$temp_dir"' RETURN
|
|
322
|
+
bin_dir="$temp_dir/bin"
|
|
323
|
+
mkdir -p "$bin_dir"
|
|
324
|
+
fake_pi="$bin_dir/pi"
|
|
325
|
+
fake_node="$bin_dir/node"
|
|
326
|
+
fake_node_marker="$temp_dir/fake-node-used"
|
|
327
|
+
env_capture="$temp_dir/fake-pi.env"
|
|
328
|
+
cat >"$fake_pi" <<EOF_SELFTEST_PI
|
|
329
|
+
#!/usr/bin/env node
|
|
330
|
+
const { writeFileSync } = require("node:fs");
|
|
331
|
+
writeFileSync("$env_capture", Object.entries(process.env).map(([key, value]) => key + "=" + (value ?? "")).join("\\n") + "\\n", "utf8");
|
|
332
|
+
EOF_SELFTEST_PI
|
|
333
|
+
cat >"$fake_node" <<EOF_SELFTEST_NODE
|
|
334
|
+
#!/usr/bin/env bash
|
|
335
|
+
echo fake-node-used > "$fake_node_marker"
|
|
336
|
+
exit 99
|
|
337
|
+
EOF_SELFTEST_NODE
|
|
338
|
+
chmod +x "$fake_pi" "$fake_node"
|
|
339
|
+
|
|
340
|
+
ENV_BIN="$(smoke_resolve_cmd env)"
|
|
341
|
+
NODE_BIN="$(smoke_resolve_cmd node)"
|
|
342
|
+
smoke_load_cursor_sdk_event_debug_env_names "$NODE_BIN" "$ROOT/shared/cursor-sdk-event-debug-env.mjs"
|
|
343
|
+
hostile_path="$bin_dir:$PATH"
|
|
344
|
+
[[ "$(smoke_build_sealed_node_path "$NODE_BIN" "")" != *: ]] || fail "self-test failed: empty inherited PATH left a trailing PATH separator"
|
|
345
|
+
SEALED_PATH="$(smoke_build_sealed_node_path "$NODE_BIN" "$hostile_path")"
|
|
346
|
+
build_smoke_env_arrays
|
|
347
|
+
node_dir="$(dirname "$NODE_BIN")"
|
|
348
|
+
|
|
349
|
+
PI_CURSOR_SETTING_SOURCES=all \
|
|
350
|
+
PI_CURSOR_SDK_EVENT_DEBUG=1 \
|
|
351
|
+
PI_CURSOR_SDK_EVENT_DEBUG_DIR="$temp_dir/debug-dir" \
|
|
352
|
+
PI_CURSOR_SDK_EVENT_DEBUG_RUN_DIR="$temp_dir/debug-run-dir" \
|
|
353
|
+
PI_CURSOR_SDK_EVENT_DEBUG_SESSION_DIR="$temp_dir/debug-session-dir" \
|
|
354
|
+
PI_CURSOR_SDK_EVENT_DEBUG_STDERR=1 \
|
|
355
|
+
"${NONE_ENV[@]}" "$fake_pi" --version
|
|
356
|
+
[[ ! -e "$fake_node_marker" ]] || fail "self-test failed: sealed PATH still used hostile fake node"
|
|
357
|
+
captured_path="$(awk -F= '$1 == "PATH" { print substr($0, 6); exit }' "$env_capture")"
|
|
358
|
+
[[ "${captured_path%%:*}" == "$node_dir" ]] || fail "self-test failed: PATH did not start with resolved node dir"
|
|
359
|
+
grep -qx 'PI_CURSOR_SETTING_SOURCES=none' "$env_capture" || fail "self-test failed: isolated env did not force PI_CURSOR_SETTING_SOURCES=none"
|
|
360
|
+
for name in "${SMOKE_CURSOR_SDK_EVENT_DEBUG_ENV_NAMES[@]}"; do
|
|
361
|
+
if grep -q "^${name}=" "$env_capture"; then
|
|
362
|
+
fail "self-test failed: $name was not cleared"
|
|
363
|
+
fi
|
|
364
|
+
done
|
|
365
|
+
|
|
366
|
+
PI_CURSOR_SETTING_SOURCES=all "${DEFAULT_ENV[@]}" "$fake_pi" --version
|
|
367
|
+
if grep -q '^PI_CURSOR_SETTING_SOURCES=' "$env_capture"; then
|
|
368
|
+
fail "self-test failed: default-settings env did not unset PI_CURSOR_SETTING_SOURCES"
|
|
369
|
+
fi
|
|
370
|
+
printf '[smoke] self-test PASS\n'
|
|
341
371
|
}
|
|
342
372
|
|
|
343
373
|
if [[ "${1:-}" == "-h" || "${1:-}" == "--help" ]]; then
|
|
344
374
|
print_help
|
|
345
375
|
exit 0
|
|
346
376
|
fi
|
|
377
|
+
if [[ "${1:-}" == "--self-test" ]]; then
|
|
378
|
+
run_self_test
|
|
379
|
+
exit 0
|
|
380
|
+
fi
|
|
347
381
|
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
382
|
+
PI_BIN="$(smoke_resolve_cmd pi)"
|
|
383
|
+
NODE_BIN="$(smoke_resolve_cmd node)"
|
|
384
|
+
NPM_BIN="$(smoke_resolve_cmd npm)"
|
|
385
|
+
RG_BIN="$(smoke_resolve_cmd rg)"
|
|
386
|
+
TMUX_BIN="$(smoke_resolve_cmd tmux)"
|
|
387
|
+
ENV_BIN="$(smoke_resolve_cmd env)"
|
|
388
|
+
smoke_load_cursor_sdk_event_debug_env_names "$NODE_BIN" "$ROOT/shared/cursor-sdk-event-debug-env.mjs"
|
|
389
|
+
SEALED_PATH="$(smoke_build_sealed_node_path "$NODE_BIN" "$PATH")"
|
|
390
|
+
build_smoke_env_arrays
|
|
391
|
+
if [[ "$SHELL_BIN" != /* ]]; then
|
|
392
|
+
SHELL_BIN="$(smoke_resolve_cmd "$SHELL_BIN")"
|
|
393
|
+
fi
|
|
394
|
+
PI_BASE=(
|
|
395
|
+
"$PI_BIN" -e "$ROOT"
|
|
396
|
+
--cursor-no-fast
|
|
397
|
+
--model cursor/composer-2.5
|
|
398
|
+
)
|
|
352
399
|
|
|
353
400
|
if [[ -z "${CURSOR_API_KEY:-}" ]]; then
|
|
354
|
-
|
|
401
|
+
log "CURSOR_API_KEY is unset; relying on stored pi auth or other supported Cursor auth"
|
|
355
402
|
fi
|
|
356
403
|
|
|
357
404
|
mkdir -p "$SMOKE_DIR"
|
|
358
405
|
printf '%s\n' "$SMOKE_DIR" >"$SMOKE_DIR/smoke-dir.txt"
|
|
359
406
|
|
|
360
407
|
log "SMOKE_DIR=$SMOKE_DIR"
|
|
408
|
+
log "pi=$PI_BIN"
|
|
409
|
+
log "node=$NODE_BIN"
|
|
410
|
+
log "npm=$NPM_BIN"
|
|
411
|
+
log "tmux=$TMUX_BIN"
|
|
361
412
|
log "partial live smoke: prereq, basic, default-settings, noninteractive-math, tui, steering, diagnostics, jsonl"
|
|
362
413
|
|
|
363
|
-
|
|
414
|
+
"${BASE_ENV[@]}" "$PI_BIN" --version | tee "$SMOKE_DIR/prereq.pi-version.txt"
|
|
415
|
+
"${BASE_ENV[@]}" "$NPM_BIN" --prefix "$ROOT" ls @cursor/sdk @earendil-works/pi-coding-agent @earendil-works/pi-ai @earendil-works/pi-tui | tee "$SMOKE_DIR/prereq.npm-ls.txt"
|
|
416
|
+
|
|
417
|
+
if ! "${NONE_ENV[@]}" "${PI_BASE[@]}" --list-models cursor 2>"$SMOKE_DIR/prereq.stderr.txt" | tee "$SMOKE_DIR/prereq.models.txt" | "$RG_BIN" -q "composer-2\\.5"; then
|
|
364
418
|
if ! model_listed "$SMOKE_DIR/prereq.stderr.txt"; then
|
|
365
419
|
fail "cursor/composer-2.5 not listed"
|
|
366
420
|
fi
|
|
@@ -368,34 +422,34 @@ fi
|
|
|
368
422
|
log "prereq PASS"
|
|
369
423
|
|
|
370
424
|
run_direct basic 600 retry-empty-output "PI_CURSOR_SMOKE_OK" "PI_CURSOR_SMOKE_OK" \
|
|
371
|
-
|
|
425
|
+
"${NONE_ENV[@]}" "${PI_BASE[@]}" \
|
|
372
426
|
--session-dir "$SMOKE_DIR/basic" \
|
|
373
427
|
--no-tools \
|
|
374
428
|
-p 'Live smoke. Reply exactly: PI_CURSOR_SMOKE_OK'
|
|
375
429
|
|
|
376
430
|
run_direct default-settings 300 strict "PRODUCT=42" "PRODUCT=42" \
|
|
377
|
-
"${PI_BASE[@]}" \
|
|
431
|
+
"${DEFAULT_ENV[@]}" "${PI_BASE[@]}" \
|
|
378
432
|
--session-dir "$SMOKE_DIR/default-settings" \
|
|
379
433
|
--no-tools \
|
|
380
434
|
-p 'Default settings smoke. Include PRODUCT=42 in the final answer.'
|
|
381
435
|
|
|
382
436
|
run_direct noninteractive-math 300 strict "SUM=42" "SUM=42" \
|
|
383
|
-
|
|
437
|
+
"${NONE_ENV[@]}" "${PI_BASE[@]}" \
|
|
384
438
|
--session-dir "$SMOKE_DIR/noninteractive-math" \
|
|
385
439
|
--no-tools \
|
|
386
440
|
-p 'Noninteractive math smoke. Compute 19 + 23. Reply only with SUM=42.'
|
|
387
441
|
|
|
388
442
|
run_tui_math_footer_poll tui 420 \
|
|
389
|
-
|
|
443
|
+
"${NONE_ENV[@]}" "${PI_BASE[@]}" \
|
|
390
444
|
--session-dir "$SMOKE_DIR/tui" \
|
|
391
445
|
--no-tools \
|
|
392
446
|
'TUI smoke. Compute 19 + 23. Reply only with SUM=<number>.'
|
|
393
447
|
|
|
394
448
|
run_tmux steering 420 1 \
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
449
|
+
"${NONE_ENV[@]}" "SMOKE_SESSION_DIR=$SMOKE_DIR/steering" "PI_BIN=$PI_BIN" "$NODE_BIN" "$ROOT/scripts/steering-rpc-smoke.mjs"
|
|
450
|
+
"$RG_BIN" -q '"steerOk":true' "$SMOKE_DIR/steering.stdout.txt" || fail "steering missing steerOk"
|
|
451
|
+
"$RG_BIN" -q '"steerChain":true' "$SMOKE_DIR/steering.stdout.txt" || fail "steering missing steerChain"
|
|
452
|
+
"$RG_BIN" -q "already has active run|AgentBusyError" "$SMOKE_DIR/steering.stdout.txt" "$SMOKE_DIR/steering.stderr.txt" && fail "steering hit AgentBusyError" || true
|
|
399
453
|
|
|
400
454
|
forbidden_files="$(find "$SMOKE_DIR" -type f \( -name '*stderr.txt' -o -name '*capture*.txt' \) -print0 |
|
|
401
455
|
xargs -0 grep -IlE 'CURSOR_API_KEY|Bearer [A-Za-z0-9._-]+|/cursor-pi-tool-bridge/[^ ]+/mcp|127\.0\.0\.1:[0-9]+/cursor-pi-tool-bridge|apiKey|cookie|session-cookie|secret-token' || true)"
|
|
@@ -413,6 +467,6 @@ if [[ -n "$forbidden_files" ]]; then
|
|
|
413
467
|
fi
|
|
414
468
|
log "diagnostics safety PASS"
|
|
415
469
|
|
|
416
|
-
|
|
470
|
+
"$NODE_BIN" "$ROOT/scripts/validate-smoke-jsonl.mjs" "$SMOKE_DIR"
|
|
417
471
|
log "jsonl structural scan PASS"
|
|
418
|
-
log "partial live smoke checks passed (see --help for uncovered
|
|
472
|
+
log "partial live smoke checks passed (see --help for uncovered named release checks)"
|