Skip to content

chore(deps): refresh Worker and forwarder dependencies - #34

Merged
steipete merged 1 commit into
mainfrom
chore/deps-refresh-20260830
Aug 31, 2026
Merged

chore(deps): refresh Worker and forwarder dependencies#34
steipete merged 1 commit into
mainfrom
chore/deps-refresh-20260830

Conversation

@steipete

@steipete steipete commented Aug 31, 2026

Copy link
Copy Markdown
Contributor

What Problem This Solves

Refreshes the Worker dependencies and the forwarder's stale transitive lockfile entries while preserving the existing build and test gates.

Why This Change Was Made

Updates React Router from 8.3.0 to 8.3.1 and Wrangler from 4.127.0 to 4.127.1, refreshes both Bun lockfiles, and regenerates the Cloudflare runtime declarations. No direct dependencies were added or removed, and no application migration was required.

Scope Dependency updates
Worker direct react-router 8.3.0 → 8.3.1; wrangler 4.127.0 → 4.127.1
Worker transitive miniflare 5.20260826.0-alpha → 5.20260828.0-alpha; workerd 1.20260826.1 → 1.20260828.1; tsx 4.23.12 → 4.23.13; voice's nested discord-api-types 0.38.53 → 0.38.54
Forwarder transitive @types/node 25.8.0 → 25.9.5; @snazzah/davey 0.1.11 → 0.1.12 and its platform packages; @emnapi/core/runtime 1.10.0 → 1.11.3; @emnapi/wasi-threads 1.2.1 → 1.2.3; @napi-rs/wasm-runtime 1.1.4 → 1.2.3; @tybys/wasm-util 0.10.2 → 0.10.3

The forwarder's previous lockfile stored exact versions where published package metadata declares ranges. Regenerating it with Bun restores those ranges and updates the compatible dependencies; its direct manifest stays unchanged. Both lockfiles were generated by Bun 1.4.0. No direct major upgrades were available or skipped.

Reviewed the upstream React Router patch notes and Wrangler patch notes. Bun 1.4.0 and all Action pins are current: checkout 7.0.1, setup-node 7.0.0, setup-bun 2.2.0, and create-github-app-token 3.2.0. Verified the pinned SHAs against those release tags.

User Impact

Routine dependency maintenance with no intentional change to Hermit's user-facing behavior. No changelog or UI change is needed.

Evidence

Both packages pass frozen installs and typechecks. The Worker dry-run build passes. The full suite runs with its existing assertions; the local command uses a 30-second per-test timeout because the shared Mac exceeded Bun's five-second default in two ImageMagick/filesystem fixture tests. CI retains its original timeout and assertions.

bun install --frozen-lockfile
(cd forwarder && bun install --frozen-lockfile && bun run typecheck)
bun run typecheck
WRANGLER_SEND_METRICS=false bun run deploy:dry-run --outdir tmp/deps-refresh-20260830/worker
bun run test -- --timeout 30000
Worker frozen install: Checked 140 installs across 251 packages (no changes)
Forwarder frozen install: Checked 24 installs across 58 packages (no changes)
Worker typecheck: exit 0
Forwarder typecheck: exit 0
Total Upload: 7408.20 KiB / gzip: 650.16 KiB
--dry-run: exiting now.
255 pass
0 fail
184703 expect() calls
Ran 255 tests across 28 files. [158.62s]

The live check starts the actual dry-run bundle in workerd through Wrangler's installed Miniflare, then sends HTTP requests to its local listener. It checks Forms SSR, a real bundled lobster species, a missing species, HEAD, and unsupported-method handling. Synthetic configuration is used; Discord command-registration requests are intercepted locally. No production request or deployment is performed.

bun tmp/deps-refresh-20260830/live-proof.mjs
Worker listening at http://127.0.0.1:57000
GET forms.openclaw.ai/ -> 200; OpenClaw Forms
GET hermit-discord.openclaw.ai/lobsters/107253 -> 200; Homarus gammarus
GET hermit-discord.openclaw.ai/lobsters/999999999 -> 404; Lobster dossier not found
HEAD hermit-discord.openclaw.ai/lobsters/107253 -> 200; empty body
POST hermit-discord.openclaw.ai/lobsters/107253 -> 405; Method Not Allowed
Live proof passed; 2 Discord requests intercepted locally; no external requests forwarded.
Reproduce the local HTTP proof

Save this as tmp/deps-refresh-20260830/live-proof.mjs after the dry-run build:

import assert from 'node:assert/strict';
import { Miniflare, Response, convertV4MiniflareOptions } from 'miniflare';

const intercepted = [];
const runtime = new Miniflare(convertV4MiniflareOptions({
  host: '127.0.0.1', port: 0, cf: false,
  modules: true, scriptPath: 'tmp/deps-refresh-20260830/worker/entry.js',
  compatibilityDate: '2025-12-17',
  compatibilityFlags: ['nodejs_compat', 'nodejs_compat_populate_process_env'],
  bindings: {
    BASE_URL: 'http://127.0.0.1',
    DEPLOY_SECRET: 'synthetic-local-proof',
    DISCORD_CLIENT_ID: '100000000000000001',
    DISCORD_PUBLIC_KEY: '00'.repeat(32),
    DISCORD_BOT_TOKEN: 'synthetic-local-proof',
  },
  outboundService: (request) => {
    const url = new URL(request.url);
    assert.equal(url.hostname, 'discord.com');
    assert.equal(request.method, 'PUT');
    assert.match(url.pathname, /^\/api\/applications\/100000000000000001\/(?:guilds\/\d+\/)?commands$/);
    intercepted.push(request.method);
    return Response.json([]);
  },
}));

try {
  const base = await runtime.ready;
  console.log(`Worker listening at ${base.origin}`);
  for (const [host, path, method, expected, text] of [
    ['forms.openclaw.ai', '/', 'GET', 200, 'OpenClaw Forms'],
    ['hermit-discord.openclaw.ai', '/lobsters/107253', 'GET', 200, 'Homarus gammarus'],
    ['hermit-discord.openclaw.ai', '/lobsters/999999999', 'GET', 404, 'Lobster dossier not found'],
    ['hermit-discord.openclaw.ai', '/lobsters/107253', 'HEAD', 200, ''],
    ['hermit-discord.openclaw.ai', '/lobsters/107253', 'POST', 405, 'Method Not Allowed'],
  ]) {
    const response = await fetch(new URL(path, base), { method, redirect: 'manual', headers: { 'MF-Original-URL': `https://${host}${path}` } });
    const body = await response.text();
    assert.equal(response.status, expected);
    assert.ok(body.includes(text));
    if (method === 'HEAD') assert.equal(body, '');
    console.log(`${method} ${host}${path} -> ${response.status}; ${text || 'empty body'}`);
  }
  assert.ok(intercepted.length > 0);
  console.log(`Live proof passed; ${intercepted.length} Discord requests intercepted locally; no external requests forwarded.`);
} finally {
  await runtime.dispose();
}

Codex autoreview completed scoped-clean with no accepted/actionable findings at its requested default P0 threshold.

CI Reasoning

The orchestrator's NORUNS observation was stale. The current default-branch commit already passed CI / Build and test. That workflow runs frozen installs and typechecks for both packages, the Worker dry-run build, and the full suite on PRs and pushes to main; it requires no production credentials.

ClawSweeper Dispatch is separate event-driven operations automation, not a build/test gate; its latest observed default-branch run succeeded. There is no scheduled GitHub Actions monitoring workflow in this checkout. Cloudflare Builds remains the production deploy owner after a reviewed merge to main.

The PR passed CI / Build and test in 2m22s, including the full suite with the unchanged CI timeout. CodeQL and ClawSweeper Dispatch also passed. No CI jobs or assertions were weakened, skipped, or removed by this change.

This PR is for maintainer review and landing; it has not been merged or released.

@clawsweeper

clawsweeper Bot commented Aug 31, 2026

Copy link
Copy Markdown

🦞👀
ClawSweeper picked this up.

Pull request received. I will update this pull request when review starts.

@steipete
steipete merged commit 38f929b into main Aug 31, 2026
7 checks passed
@steipete
steipete deleted the chore/deps-refresh-20260830 branch August 31, 2026 07:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant