@workos/quickstudy 0.8.0 → 0.8.1

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@workos/quickstudy",
3
- "version": "0.8.0",
3
+ "version": "0.8.1",
4
4
  "description": "An open-source, company-agnostic eval harness for measuring whether coding agents can complete real integration tasks, across an agent x feature x framework x surface matrix.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -9,7 +9,7 @@ export const EMBEDDED_BUILD_INFO: {
9
9
  // (the `x-release-please-version` marker anchors the replacement). It is
10
10
  // restored as-is after a binary build (scripts/build-binary.ts), so the
11
11
  // committed source `--version` stays in lockstep with package.json.
12
- version: "0.8.0", // x-release-please-version
12
+ version: "0.8.1", // x-release-please-version
13
13
  revision: null,
14
14
  dirty: null,
15
15
  sourceHash: null,
package/src/probe.ts CHANGED
@@ -196,14 +196,41 @@ export async function readAppLogTail(exec: ProbeExecFn, lines = 40): Promise<str
196
196
  }
197
197
 
198
198
  /** Kill the backgrounded dev server (process group first, pid as fallback). */
199
+ /**
200
+ * Every process in the app's process group, read from /proc so no `ps`,
201
+ * `pkill` or external `kill` is needed. dash's builtin `kill` rejects a
202
+ * negative pid ("Illegal number"), so `kill -- -<pgid>` only ever worked
203
+ * under bash and busybox; on the Debian-based sandbox images it failed and
204
+ * the fallback signalled the group leader alone.
205
+ */
206
+ const GROUP_MEMBERS_SH =
207
+ // After the ")" that closes the command name, /proc/<pid>/stat reads
208
+ // "<state> <ppid> <pgrp> …"; a zombie (state Z) is dead and only unreaped.
209
+ 'members() { for d in /proc/[0-9]*; do [ -r "$d/stat" ] || continue; ' +
210
+ 'set -- $(sed "s/^.*) //" "$d/stat" 2>/dev/null); ' +
211
+ '[ "$3" = "$pid" ] && [ "$1" != "Z" ] && echo "${d#/proc/}"; done; }; ' +
212
+ // Without /proc (a host runtime on macOS) fall back to the shell's group kill.
213
+ 'signal() { if [ -d /proc/self ]; then m=$(members); [ -n "$m" ] || return 1; kill -s "$1" $m 2>/dev/null; ' +
214
+ 'else kill -s "$1" -- "-$pid" 2>/dev/null; fi; }; ' +
215
+ 'alive() { if [ -d /proc/self ]; then [ -n "$(members)" ]; else kill -0 -- "-$pid" 2>/dev/null; fi; }; ';
216
+
199
217
  export async function stopBackgroundApp(exec: ProbeExecFn): Promise<void> {
218
+ // SIGTERM the group, give it five seconds, then SIGKILL whatever is left.
219
+ // Dev servers that fork a worker outlive a TERM to the leader: Next.js's
220
+ // `start-server` child stayed bound to the port after `npm run dev` exited,
221
+ // so the next probe booted on another port while the stale server answered
222
+ // the probe's requests (500s on routes it had never compiled).
200
223
  await exec(
201
224
  [
202
225
  "sh",
203
226
  "-c",
204
- `pid="$(cat ${APP_PID_PATH} 2>/dev/null)"; [ -z "$pid" ] || kill -TERM -- "-$pid" 2>/dev/null || kill "$pid" 2>/dev/null || true`,
227
+ `pid="$(cat ${APP_PID_PATH} 2>/dev/null)"; [ -n "$pid" ] || exit 0; ` +
228
+ GROUP_MEMBERS_SH +
229
+ 'signal TERM || kill -s TERM "$pid" 2>/dev/null || true; ' +
230
+ 'i=0; while [ "$i" -lt 10 ] && alive; do sleep 0.5; i=$((i + 1)); done; ' +
231
+ 'signal KILL || kill -s KILL "$pid" 2>/dev/null || true',
205
232
  ],
206
- { timeoutMs: 10_000 },
233
+ { timeoutMs: 20_000 },
207
234
  );
208
235
  }
209
236