cursedops 0.10.16 → 0.10.17

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 (2) hide show
  1. package/package.json +1 -1
  2. package/src/edgeFetch.ts +11 -6
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cursedops",
3
- "version": "0.10.16",
3
+ "version": "0.10.17",
4
4
  "description": "The build-and-ops answers this generation's apps wrote independently and identically: finding a generation's roots — and printing a command that runs when pasted — without knowing a path, the generation's whole-tree laws run over one repo from a checkout or a worktree, macOS launchd agent install/replace/remove and the live port a job serves, the scaffolding and verdicts of a deployed smoke (origin probe, the smoke's own environment, a network that lies about DNS, a settled version), the static-serving helpers eight apps copied — the path-traversal guard among them — the API floor that keeps an unmatched /api/... from ever being answered with the app shell, the commit and dirty flag a checkout-served process reports, the Cloudflare Worker deploy toolkit four apps copied (the deploy sequence, exact-set secrets over a pipe, origin-first rollback, the curl edge fetch, the row-for-row D1 import proof, the billed-CPU tail check around a deploy's walk and smoke, and each app's worker:secrets and worker:smoke main as one function of its data), the relay a Worker fronts a Mac-bound app with (the Durable Object, the frames, the Mac's dialer and key rotation — lifted from station for roms — and the signed-in stage walk's skeleton and the relay app's whole worker:deploy), the Worker import-graph and await-port checks every Worker app's suite runs over its own source, and the public-surface ratchet three published libraries each carried a forked copy of. Mechanism only — no app knows its name from here. Bun, zero runtime dependencies (typescript is an optional peer, for public-surface only), ships source.",
5
5
  "type": "module",
6
6
  "scripts": {
package/src/edgeFetch.ts CHANGED
@@ -73,15 +73,20 @@ const EDGE_RETRIES = 2;
73
73
  * · 6 resolve, 7 connect, 35 TLS handshake — the request never left this machine, so a replay
74
74
  * is always safe, whatever the method;
75
75
  * · 52 empty reply, 56 receive failure — the request MAY have reached the Worker and done its
76
- * work, so these are replayed only for a method that is safe to run twice (never a POST).
76
+ * work, so these are replayed only for a method that is safe to run twice (never a POST);
77
+ * · 28 timeout — the far end may still be working, so the same rule, and ONCE only: a replay
78
+ * costs a whole `--max-time`, and a Worker that is really down must not hold a smoke for
79
+ * three of them. Measured 2026-09-26: flix's prod smoke went red on one `curl exit 28` for
80
+ * `GET /healthz` while the same URL answered 200 in 0.2 s seconds later (task 2190).
77
81
  *
78
- * Every other exit — 28 (timeout) above all, where the far end may still be working — and every
79
- * HTTP status, whatever it is, is returned exactly as before.
82
+ * Every other exit, and every HTTP status, whatever it is, is returned exactly as before.
80
83
  */
81
- function retryableCurlFailure(exit: number | null, stdout: Buffer, method = "GET"): boolean {
84
+ function retryableCurlFailure(exit: number | null, stdout: Buffer, method = "GET", retry = 1): boolean {
82
85
  if (stdout.length > 0 || exit === null) return false;
83
86
  if (exit === 6 || exit === 7 || exit === 35) return true;
84
- return (exit === 52 || exit === 56) && ["GET", "HEAD", "OPTIONS", "PUT", "DELETE"].includes(method.toUpperCase());
87
+ const replayable = ["GET", "HEAD", "OPTIONS", "PUT", "DELETE"].includes(method.toUpperCase());
88
+ if (exit === 28) return replayable && retry === 1;
89
+ return (exit === 52 || exit === 56) && replayable;
85
90
  }
86
91
 
87
92
  function digCloudflare(host: string): string | null {
@@ -170,7 +175,7 @@ export function createEdgeFetch(options: EdgeFetchOptions = {}): (url: string, i
170
175
  }
171
176
  try {
172
177
  let out = curl([...head(), ...args, target.toString()]);
173
- for (let retry = 1; retry <= EDGE_RETRIES && retryableCurlFailure(out.status, out.stdout, init.method); retry++) {
178
+ for (let retry = 1; retry <= EDGE_RETRIES && retryableCurlFailure(out.status, out.stdout, init.method, retry); retry++) {
174
179
  await new Promise((r) => setTimeout(r, options.retryDelayMs?.(retry) ?? 500 * retry));
175
180
  // `head()` again: a host with no pin yet is asked again, so a retry can find the address.
176
181
  out = curl([...head(), ...args, target.toString()]);